% \iffalse meta-comment
%
%
% bookshelf.dtx is copyright © 2020-2024 by Peter Flynn
% <
[email protected]> and Boris Veytsman <
[email protected]>
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any later
% version. The latest version of this license is in:
%
%
http://www.latex-project.org/lppl.txt
%
% and version 1.3c or later is part of all distributions of
% LaTeX version 2008-06-01 or later.
%
% This work has the LPPL maintenance status ‘maintained’.
%
% The current maintainer of this work is Peter Flynn <
[email protected]>
%
% This work consists of the files bookshelf.dtx and bookshelf.ins,
% the derived file ,
% and any other ancillary files listed in the MANIFEST.
%
% \fi
% \iffalse
%<*driver>
\ProvidesFile{bookshelf.dtx}
%</driver>
%<class>\NeedsTeXFormat{LaTeX2e}[2017/04/15]
%<class>\ProvidesClass{bookshelf}
%<*class>
[2024/10/09 v1.2 Turn your bibliography into a bookshelf image]
%</class>
%<*driver>
\RequirePackage{fix-cm}% included by default.
\PassOptionsToPackage{svgnames}{xcolor}% xcolor/dox/hyperref implied
\documentclass[12pt]{ltxdoc}
%%
%% Packages added for documentation
%%
\usepackage[noindex]{dox}% used by default. (0)%
\makeatletter
\doxitem[idxtype=attribute]{Attribute}{CPK@attribute}{attributes}
\makeatother
\makeatletter
\doxitem[idxtype=attributevalue]{AttributeValue}{CPK@attributevalue}{attribute values}
\makeatother
\makeatletter
\doxitem[idxtype=class]{Class}{CPK@class}{classes}
\makeatother
\makeatletter
\doxitem[idxtype=colour]{Colour}{CPK@colour}{colours}
\makeatother
\makeatletter
\doxitem[idxtype=counter]{Counter}{CPK@counter}{counters}
\makeatother
\makeatletter
\doxitem[idxtype=DTD]{DTD}{CPK@dtd}{DTDs/Schemas}
\makeatother
\makeatletter
\doxitem[idxtype=element]{Element}{CPK@element}{element types}
\makeatother
\makeatletter
\doxitem[idxtype=entity]{Entity}{CPK@entity}{entities}
\makeatother
\makeatletter
\doxitem[idxtype=error]{Error}{CPK@error}{errors}
\makeatother
\makeatletter
\doxitem[idxtype=field]{Field}{CPK@field}{fields}
\makeatother
\makeatletter
\doxitem[idxtype=file]{File}{CPK@file}{files}
\makeatother
\makeatletter
\doxitem[idxtype=font]{Font}{CPK@font}{fonts}
\makeatother
\makeatletter
\doxitem[idxtype=function]{Function}{CPK@function}{functions}
\makeatother
\makeatletter
\doxitem[idxtype=language]{Language}{CPK@language}{languages}
\makeatother
\makeatletter
\doxitem[macrolike,idxtype=length]{Length}{CPK@length}{lengths}
\makeatother
\makeatletter
\doxitem[idxtype=mode]{Mode}{CPK@mode}{modes}
\makeatother
\makeatletter
\doxitem[idxtype=option]{Option}{CPK@option}{options}
\makeatother
\makeatletter
\doxitem[idxtype=package]{Package}{CPK@package}{packages}
\makeatother
\makeatletter
\doxitem[idxtype=variable]{Variable}{CPK@variable}{variables}
\makeatother
\makeatletter
\doxitem[idxtype=parameter]{Parameter}{CPK@parameter}{parameters}
\makeatother
\makeatletter
\doxitem[macrolike,idxtype=switch]{Switch}{CPK@switch}{switches}
\makeatother
\makeatletter
\doxitem[idxtype=template]{Template}{CPK@template}{templates}
\makeatother
\makeatletter
\doxitem[idxtype=typeface]{Typeface}{CPK@typeface}{typefaces}
\makeatother
\makeatletter
\doxitem[macrolike,idxtype=box]{Box}{CPK@box}{boxes}
\makeatother
\newcommand{\LabelFont}[2][\relax]{\strut
{\fontencoding\encodingdefault
\fontfamily{lmtt}\fontseries{lc}#1\selectfont#2}\space}
\makeatletter
\let\CPK@macro\macro\let\CPK@endmacro\endmacro
\makeatother
\makeatletter
\let\CPK@environment\environment\let\CPK@endenvironment\endenvironment
\makeatother
\makeatletter
\def\PrintAttributeName#1{\LabelFont{@#1}}
\makeatother
\def\PrintAttributeValueName#1{\LabelFont{"#1"}}
\def\PrintClassName#1{\LabelFont[\fontfamily{lmss}]{#1}}
\def\PrintColourName#1{\LabelFont[\color{#1}]{#1}}
\def\PrintCounterName#1{\LabelFont{#1}}
\def\PrintDTDName#1{\LabelFont{#1}}
\def\PrintElementName#1{\LabelFont{<#1>}}
\def\PrintEntityName#1{\LabelFont{\}}
\def\PrintEnvironmentName#1{\LabelFont[\fontfamily{lmss}]{#1}}
\def\PrintErrorName#1{\LabelFont[\color{Red}!]{#1}}
\def\PrintFunctionName#1{\LabelFont[\bfseries\itshape]{#1}}
\def\PrintLanguageName#1{\LabelFont{#1}}
\def\PrintLengthName#1{\LabelFont{#1}}
\def\PrintMacroName#1{\LabelFont{#1}}
\def\PrintModeName#1{\LabelFont[\sffamily]{\textlangle#1\textrangle}}
\def\PrintOptionName#1{\LabelFont[\bfseries]{#1}}
\def\PrintPackageName#1{\LabelFont[\fontfamily{lmss}]{#1}}
\def\PrintSwitchName#1{\LabelFont{#1}}
\def\PrintTemplateName#1{\LabelFont[\bfseries]{#1}}
\def\PrintVariableName#1{\LabelFont[\ttfamily]{#1}}
\def\PrintParameterName#1{\LabelFont[\ttfamily]{#1}}
\def\PrintFieldName#1{\LabelFont[\ttfamily]{#1}}
%% fontenc omit: conflict: fontspec (3)
%% inputenc omit: conflict: fontspec (6)
\usepackage{fontspec}% part/@conformance=xelatex detected. (7)%
\renewcommand{\textsc}[1]{{\small\MakeTextUppercase{#1}}}
\usepackage{noto}% requested by author (15)%
\usepackage{luximono}% requested by author (16)%
\usepackage{mflogo}% used by default. (36)%
\usepackage[british]{babel}% used by default. (41)%
\usepackage{calc}% used by default. (50)%
\makeatletter
{\scriptsize
\global\advance\@totalleftmargin by1em
\global\advance\MacroIndent by.5em}
\makeatother
\usepackage{ccaption}% used by default. (53)%
\captionnamefont{\bfseries}
\captionstyle{\raggedright}
\usepackage[inline]{enumitem}% use of 'variablelist' detected (57)%
\setlist[description]{style=unboxed}
\setlist[itemize]{leftmargin=2em}
\setlist[enumerate]{leftmargin=2em}
\newlist{inlineenum}{enumerate*}{1}
\setlist[inlineenum,1]{label=\emph{\alph*}),
itemjoin={{; }},itemjoin*={{; and }}}
\usepackage{fancyhdr}% requested by author (59)%
\makeatletter
\pagestyle{fancy}
\cfoot{}
\lhead{\footnotesize\rightmark}
\rhead{\small\thepage}
\rfoot{\footnotesize The \LaTeX\
\textsf{\SIL@docname} \SIL@doctype}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
\makeatother
\usepackage{relsize}% use of 'acronym' detected (65)%
\usepackage{textcase}% used by default. (68)%
\usepackage{float}% used by default. (70)%
\renewcommand{\topfraction}{.85}
\renewcommand{\bottomfraction}{.7}
\renewcommand{\textfraction}{.15}
\renewcommand{\floatpagefraction}{.66}
\renewcommand{\dbltopfraction}{.66}
\renewcommand{\dblfloatpagefraction}{.66}
\setcounter{topnumber}{9}
\setcounter{bottomnumber}{9}
\setcounter{totalnumber}{20}
\setcounter{dbltopnumber}{9}
\usepackage[level]{fmtcount}% xref/@linkend➝listitem/xml:id detected. (71)%
\usepackage[a4paper,left=30mm,top=25mm,
textwidth=150mm,textheight=225mm,headheight=15pt]{geometry}% used by
% default. (72)%
\usepackage{biblatex}
\usepackage{hypdoc}% requested by author (78)%
\hypersetup{linkcolor=DarkBlue,urlcolor=Blue,citecolor=Red}
\ExecuteBibliographyOptions{maxcitenames=1}
\DeclareFieldFormat{citehyperref}{%
\DeclareFieldAlias{bibhyperref}{noformat}% Avoid nested links
\bibhyperref{#1}}
\DeclareFieldFormat{textcitehyperref}{%
\DeclareFieldAlias{bibhyperref}{noformat}% Avoid nested links
\bibhyperref{%
#1%
\ifbool{cbx:parens}
{\bibcloseparen\global\boolfalse{cbx:parens}}
{}}}
\savebibmacro{cite}
\savebibmacro{textcite}
\renewbibmacro*{cite}{%
\printtext[citehyperref]{%
\restorebibmacro{cite}%
\usebibmacro{cite}}}
\renewbibmacro*{textcite}{%
\ifboolexpr{
( not test {\iffieldundef{prenote}} and
test {\ifnumequal{\value{citecount}}{1}} )
or
( not test {\iffieldundef{postnote}} and
test {\ifnumequal{\value{citecount}}{\value{citetotal}}} )
}
{\DeclareFieldAlias{textcitehyperref}{noformat}}
{}%
\printtext[textcitehyperref]{%
\restorebibmacro{textcite}%
\usebibmacro{textcite}}}
\usepackage{listings}% use of 'programlisting' detected (85)%
\lstdefinelanguage{dummy}
{morekeywords={dummy}}
\lstdefinelanguage{Makefile}
{otherkeywords={.PHONY,.DEFAULT},%
morekeywords={PHONY,DEFAULT,shell,ifeq,else,endif},%
keywordsprefix={.},%
moredelim=[l][\color{Green}]{:},%
morecomment=[l]{\#},%
moredelim=[s][\color{Blue}]{\$(}{)}%
}
\lstdefinelanguage{DocBook}[]{XML}
{morekeywords={abstract,address,affiliation,annotation,arg,
author,book,chapter,classname,cmdsynopsis,command,
constraintdef,contrib,copyright,cover,date,email,emphasis,
envar,filename,firstname,footnote,guibutton,guilabel,
guimenu,guimenuitem,guisubmenu,holder,info,itemizedlist,
listitem,literal,member,option,orderedlist,orgdiv,orgname,
package,para,parameter,part,personname,phrase,procedure,
productname,programlisting,quote,refsection,remark,
constructorsynopsis,methodparan,modifier,funcparams,olink,
bibliography,biblioentry,biblioset,subtitle,artpagenums,
volumenum,issuenum,DOCTYPE,SYSTEM,xml:id,releaseinfo,
replaceable,revdescription,revhistory,revision,sect1,sect2,
sect3,sect4,seg,seglistitem,segmentedlist,segtitle,
simplelist,step,surname,systemitem,tag,term,title,uri,
userinput,variablelist,varlistentry,wordasword,xref,year,
xlink:href}}
\makeatletter
\lstdefinelanguage{bash}
{morestring=[s]{[]},morekeywords={exit,logout,yes,no,@,
password,ssh,URL,cd,dvips,latex,ls,makeindex,man,mkdir,
pdflatex,sudo,texconfig,texdoc,updmap,xelatex,biber,
latexmk,bibtex}}
\makeatother
\lstdefinelanguage{APA}[]{XML}
{morekeywords={TTL}}
\lstdefinelanguage{OOXML}[]{XML}
{morekeywords={w:p,w:pPr,w:pStyle,w:rPr,w:rFonts,
w:r,w:t,w:lang}}
\lstdefinelanguage{SGML}[]{XML}
{morekeywords={sec,ttl}}
\lstdefinelanguage{DTD}[]{XML}
{morekeywords={ELEMENT,ENTITY,ATTLIST,CDATA,ID,REQUIRED,
IMPLIED,PCDATA}}
\lstdefinelanguage{Runoff}
{morekeywords={h1}}
\lstdefinelanguage{GML}
{morekeywords={h1}}
\lstdefinelanguage{Scribe}
{morekeywords={Heading},morestring=[s]{[]}}
\lstdefinelanguage{RTF}[]{TeX}
{moretexcs={rtf,ansi,deff,adeflang,fonttbl,f,froman,fprq,
fcharset,f1,fswiss,falt,fnil,colortbl,red,green,blue,
stylesheet,s,snext,nowidctlpar,hyphen,hyphlead,hyphtrail,
hyphmax,cf,kerning,dbch,af,langfe,afs,alang,loch,fs,
pgndec,pard,plain,qc,sb,sa,keepn,b,ab,rtlch,ltrch,par}}
\lstdefinelanguage{TEI}[]{XML}
{morekeywords={TEI,TEI.2,teiHeader,fileDesc,sourceDesc,
titleStmt,title,author,editor,respStmt,resp,name,
editionStmt,edition,text,body,publicationStmt,publisher,
div,div1,placeName,lg,l,s,cl,phr,w,list,distinct,p,pb,
mls,div2,head,num,val,app,lem,rdg,q,sup,uncl,note,
DOCTYPE,SYSTEM,xml:id}}[keywords,comments,strings]
\lstdefinelanguage{XSLT2}[]{XML}
{morekeywords={xsl:stylesheet,xsl:transform,
xsl:apply-imports,xsl:attribute-set,xsl:decimal-format,
xsl:import,xsl:include,xsl:key,xsl:namespace-alias,
xsl:output,xsl:param,
xsl:preserve-space,xsl:strip-space,xsl:template,
xsl:variable,xsl:character-map,xsl:function,
xsl:import-schema,xsl:param,xsl:variable,
xsl:apply-imports,xsl:apply-templates,xsl:attribute,
xsl:call-template,xsl:choose,xsl:comment,xsl:copy,
xsl:copy-of,xsl:element,xsl:fallback,xsl:for-each,
xsl:if,xsl:message,xsl:number,xsl:otherwise,
xsl:processing-instruction,xsl:text,xsl:value-of,
xsl:variable,xsl:when,xsl:with-param,xsl:sort,
xsl:for-each-group,xsl:next-match,xsl:analyze-string,
xsl:namespace,xsl:result-document,xsl:copy,
xsl:fallback,xsl:document,xsl:sequence,
xsl:matching-substring,xsl:non-matching-substring,
xsl:perform-sort,xsl:output-character},
alsodigit={-}}
\lstdefinelanguage{LaTeXe}[LaTeX]{TeX}
{morekeywords = {selectlanguage,foreignlanguage,
textbrokenbar,textlangle,textrangle,subsection,url,
chapter,tableofcontents,part,subsubsection,paragraph,
subparagraph,maketitle,setlength,listoffigures,
listoftables,color,arraybackslash,includegraphics,
textcite,parencite,graphicspath,lstinline,
DeclareLanguageMapping,textcolor,definecolor,colorbox,
fcolorbox,RequirePackage,PassOptionsToPackage}}
\lstdefinelanguage{BIBTeX}{
morekeywords = {title,author,edition,publisher,year,
address},
morestring=[b]",
}
\lstdefinelanguage{Email}{
morekeywords={From,Subject,To,Date},
}
\lstset{defaultdialect=LaTeXe,frame=single,
framesep=.5em,backgroundcolor=\color{AliceBlue},
rulecolor=\color{LightSteelBlue},framerule=1pt}
\lstloadlanguages{LaTeXe,DocBook,XML,XSLT2,bash}
\lstdefinelanguage{XMLFRAG}{tag=**[s]<>}[html]
\lstnewenvironment{listingsdoc}
{\lstset{language={[LaTeX]TeX}}}
{}
\newcommand\basicdefault[1]{\footnotesize
\color{Black}\ttfamily#1}
\lstset{basicstyle=\basicdefault{\spaceskip.5em}}
\lstset{literate=
{§}{{\S}}1
{©}{{\raisebox{.125ex}{\copyright}\enspace}}1
{«}{{\guillemotleft}}1
{»}{{\guillemotright}}1
{Á}{{\'A}}1
{Ä}{{\"A}}1
{É}{{\'E}}1
{Í}{{\'I}}1
{Ó}{{\'O}}1
{Ö}{{\"O}}1
{Ú}{{\'U}}1
{Ü}{{\"U}}1
{ß}{{\ss}}2
{à}{{\`a}}1
{á}{{\'a}}1
{ä}{{\"a}}1
{é}{{\'e}}1
{í}{{\'i}}1
{ó}{{\'o}}1
{ö}{{\"o}}1
{ú}{{\'u}}1
{ü}{{\"u}}1
{¹}{{\textsuperscript1}}1
{²}{{\textsuperscript2}}1
{³}{{\textsuperscript3}}1
{ı}{{\i}}1
{—}{{---}}1
{’}{{'}}1
{…}{{\dots}}1
{➝}{{$leftarrow$}}1
{⮠}{{$\hookleftarrow$}}1
{␣}{{\textvisiblespace}}1,
keywordstyle=\color{DarkGreen}\bfseries,
identifierstyle=\color{DarkRed},
commentstyle=\color{Gray}\upshape,
stringstyle=\color{DarkBlue}\upshape,
emphstyle=\color{Chocolate}\upshape,
showstringspaces=false,
columns=fullflexible,
keepspaces=true}
\usepackage{makeidx}% used by default. (87)%
\makeindex
\usepackage{nicefrac}% used by default. (93)%
\def\textonehalf{\ensuremath{\nicefrac12}}
\usepackage{parskip}% requested by author (95)%
\usepackage{sectsty}% requested by author (99)%
\allsectionsfont{\sffamily\raggedright}
\renewcommand*{\descriptionlabel}[1]{\hspace\labelsep
\sffamily\bfseries #1}
\usepackage[normalem]{ulem}% use of 'link' detected (105)%
\usepackage{url}% use of 'uri' detected (106)%
\AtBeginDocument{\urlstyle{tt}}
\usepackage{varioref}% use of 'xref' detected (109)%
\vrefwarning
\labelformat{appendix}{Appendix~#1}
\makeatletter
\labelformat{chapter}{\@chapapp~#1}
\makeatother
\labelformat{section}{section~#1}
\labelformat{subsection}{section~#1}
\labelformat{subsubsection}{section~#1}
\labelformat{paragraph}{section~#1}
\labelformat{figure}{Figure~#1}
\labelformat{table}{Table~#1}
\labelformat{item}{item~#1}
\renewcommand{\reftextcurrent}{elsewhere on this
page}
\def\reftextafter{on the
\reftextvario{next}{following} page}
\usepackage{xcolor}% used by default. (117)%
\makeatletter
\@ifundefined{T}{%
\newcommand{\T}[2]{{\fontencoding{T1}%
\selectfont#2}}}{}
\makeatother
\usepackage{classpack}[2020/05/19]% used by default. (122)%
\makeatletter
\newcommand{\SIL@doctype}{class}
\newcommand{\SIL@docname}{bookshelf}
\newcommand{\SIL@docowner}{Silmaril}
\makeatother
\addbibresource{bookshelf.bib}
\allsectionsfont{\sffamily}
%
%%
%% Settings for docstrip and ltxdoc
%%
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}\raggedright
\DocInput{bookshelf.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
% Digits \0\1\2\3\4\5\6\7\8\9
% Exclamation \! Double quote \" Hash (number) \#
% Dollar \$ Percent \% Ampersand \&
% Acute accent \' Left paren \( Right paren \)
% Asterisk \* Plus \+ Comma \,
% Minus \- Point \. Solidus \/
% Colon \: Semicolon \; Less than \<
% Equals \= Greater than \> Question mark \?
% Commercial at \@ Left bracket \[ Backslash \\
% Right bracket \] Circumflex \^ Underscore \_
% Grave accent \` Left brace \{ Vertical bar \|
% Right brace \} Tilde \~}
%
% \changes{v1.0}{2024/10/02}{New maintainer. Starting rewriting}
% \changes{v0.5}{2020/05/24}{Finished initial testing: Replaced hyperref with hypdoc to avoid makeindex bug.}
% \changes{v0.4}{2020/05/19}{Completed documentation: 1) Updated note on bug in biber when processing sgml.bib; 2) Removed sgml.bib as example until problems are resolved; 3) Backtracked on attempt to use the monographic title for articles, chapters, etc; 4) Revised notes on production.}
% \changes{v0.3}{2020/05/14}{Finished first pass on documentation: 1) Done preliminary testing; 2) Script adapted for Mac OS X.}
% \changes{v0.2}{2020/05/12}{Started documentation: Code doc done, user doc still missing.}
% \changes{v0.1}{2020/05/7}{First packaged draft: Done manually from .tex file.}
%
% \GetFileInfo{bookshelf.dtx}
%
% \DoNotIndex{\@,\@@par,\@beginparpenalty,\@empty}
% \DoNotIndex{\@flushglue,\@gobble,\@input,\@makefnmark}
% \DoNotIndex{\@makeother,\@maketitle,\@namedef,\@ne}
% \DoNotIndex{\@spaces,\@tempa,\@tempb,\@tempswafalse}
% \DoNotIndex{\@tempswatrue,\@thanks,\@thefnmark,\@topnum}
% \DoNotIndex{\@@,\@elt,\@forloop,\@fortmp,\@gtempa}
% \DoNotIndex{\@totalleftmargin,\",\/,\@ifundefined,\@nil}
% \DoNotIndex{\@verbatim,\@vobeyspaces,\|,\~,\ ,\active}
% \DoNotIndex{\advance,\aftergroup,\begingroup,\bgroup}
% \DoNotIndex{\mathcal,\csname,\def,\documentstyle}
% \DoNotIndex{\dospecials,\edef,\egroup,\else,\endcsname}
% \DoNotIndex{\endgroup,\endinput,\endtrivlist}
% \DoNotIndex{\expandafter,\fi,\fnsymbol,\futurelet,\gdef}
% \DoNotIndex{\global,\hbox,\hss,\if,\if@inlabel}
% \DoNotIndex{\if@tempswa,\if@twocolumn,\ifcase,\ifcat}
% \DoNotIndex{\iffalse,\ifx,\ignorespaces,\index,\input}
% \DoNotIndex{\item,\jobname,\kern,\leavevmode,\leftskip}
% \DoNotIndex{\let,\llap,\lower,\m@ne,\next,\newpage}
% \DoNotIndex{\nobreak,\noexpand,\nonfrenchspacing}
% \DoNotIndex{\obeylines,\or,\protect,\raggedleft}
% \DoNotIndex{\rightskip,\rm,\sc,\setbox,\setcounter}
% \DoNotIndex{\small,\space,\string,\strut,\strutbox}
% \DoNotIndex{\thefootnote,\thispagestyle,\topmargin}
% \DoNotIndex{\trivlist,\tt,\twocolumn,\typeout,\vss,\vtop}
% \DoNotIndex{\xdef,\z@,\,,\@bsphack,\@esphack,\@noligs}
% \DoNotIndex{\@vobeyspaces,\@xverbatim,\`,\catcode,\end}
% \DoNotIndex{\escapechar,\frenchspacing,\glossary}
% \DoNotIndex{\hangindent,\hfil,\hfill,\hskip,\hspace,\ht}
% \DoNotIndex{\it,\langle,\leaders,\long,\makelabel}
% \DoNotIndex{\marginpar,\markboth,\mathcode,\mathsurround}
% \DoNotIndex{\mbox,\newcount,\newdimen,\newskip}
% \DoNotIndex{\nopagebreak,\parfillskip,\parindent}
% \DoNotIndex{\parskip,\penalty,\raise,\rangle,\section}
% \DoNotIndex{\setlength,\TeX,\topsep,\underline,\unskip}
% \DoNotIndex{\verb,\vskip,\vspace,\widetilde,\\,\%,\@date}
% \DoNotIndex{\@defpar,\[,\{,\},\],\count@,\ifnum,\loop}
% \DoNotIndex{\today,\uppercase,\uccode,\baselineskip}
% \DoNotIndex{\begin,\tw@,\a,\b,\c,\d,\e,\f,\g,\h,\i,\j,\k}
% \DoNotIndex{\l,\m,\n,\o,\p,\q,\r,\s,\t,\u,\v,\w,\x,\y,\z}
% \DoNotIndex{\A,\B,\C,\D,\E,\F,\G,\H,\I,\J,\K,\L,\M,\N,\O}
% \DoNotIndex{\P,\Q,\R,\S,\T,\U,\V,\W,\X,\Y,\Z,\1,\2,\3,\4}
% \DoNotIndex{\5,\6,\7,\8,\9,\0,\!,\#,\$,\&,\',\(,\)}
% \DoNotIndex{\+,\.,\:,\;,\<,\=,\>,\?,\_,\discretionary}
% \DoNotIndex{\immediate,\makeatletter,\makeatother}
% \DoNotIndex{\meaning,\newenvironment,\par,\relax}
% \DoNotIndex{\renewenvironment,\repeat,\scriptsize}
% \DoNotIndex{\selectfont,\the,\undefined,\arabic,\do}
% \DoNotIndex{\makeindex,\null,\number,\show,\write,\@ehc}
% \DoNotIndex{\@author,\@ehc,\@ifstar,\@sanitize,\@title}
% \DoNotIndex{\everypar,\if@minipage,\if@restonecol,\ifeof}
% \DoNotIndex{\ifmmode,\lccode,\newtoks,\onecolumn,\openin}
% \DoNotIndex{\p@,\SelfDocumenting,\settowidth}
% \DoNotIndex{\@resetonecoltrue,\@resetonecolfalse,\bf}
% \DoNotIndex{\clearpage,\closein,\lowercase,\@tempdima}
% \DoNotIndex{\@inlabelfalse,\selectfont,\mathcode}
% \DoNotIndex{\newmathalphabet,\rmdefault,\bfdefault}
% \DoNotIndex{\DeclareRobustCommand,\@ifpackagewith}
% \DoNotIndex{\SIL@doctype}
% \DoNotIndex{\SIL@docname}
% \DoNotIndex{\SIL@docowner}
% \DoNotIndex{\SIL@svgcolname}
% \DoNotIndex{\ifcase}
% \DoNotIndex{\SIL@svgcolval}
% \DoNotIndex{\addbibresource}
% \DoNotIndex{\immediate}
% \DoNotIndex{\input}
% \DoNotIndex{\documentclass}
% \DoNotIndex{\pagewidth}
% \DoNotIndex{\raggedright}
% \DoNotIndex{\name}
% \DoNotIndex{\SIL@topauthor}
% \DoNotIndex{\SIL@titleoneline}
% \DoNotIndex{\makebook}
% \DoNotIndex{\SILmfont}
% \DoNotIndex{\SILmfontname}
% \DoNotIndex{\vbox}
% \DoNotIndex{\fcolorbox}
% \DoNotIndex{\scalebox}
% \setcounter{tocdepth}{5}
% \setcounter{secnumdepth}{5}
% \makeatletter
% \makeatother
%
% \GetFileInfo{bookshelf.dtx}
% \title{The \textsf{bookshelf} document class\thanks{%
% This document corresponds to \textsf{bookshelf}
% \fileversion, dated \filedate.}
% \\[1em]\Large
% Turn your bibliography into a bookshelf image}
% \author{Peter Flynn\\\normalsize Silmaril
% Consultants\\[-.25ex]\normalsize Instant Textual Gratification
% Division\\\normalsize(\url{
[email protected]})\\
% Boris Veytsman\\\normalsize(\url{
[email protected]})}
% \maketitle
% \renewcommand{\abstractname}{Summary}\thispagestyle{empty}
% \begin{abstract}
% \parskip=0.5\baselineskip
% \advance\parskip by 0pt plus 2pt
% \parindent=0pt% \noindent
% The \textsf{bookshelf} package uses
% your \BibTeX{}
% bibliography file into a randomly-coloured, randomly-sized
% shelf of books, with the title and author in a randomly-chosen
% typeface. The image (converted to {\smaller JPEG} from
% {\smaller PDF}) can then be used as a background in
% \emph{Zoom},
% \emph{Teams},
% \emph{WhatsApp} etc video calls. It
% requires a little preliminary work with the supplied scripts to
% set up a list of your fonts and their stylistic variants,
% but otherwise should work on any modern \TeX{}
% distribution.\par
% \par\centering\includegraphics[width=.55\columnwidth, page=4]{spines.pdf}
% \end{abstract}
% \clearpage
% \tableofcontents
% \subsection*{Note on required and optional features}
% In this document, the keywords
% {\sffamily {\smaller MUST}}, {\sffamily {\smaller MUST NOT}}, {\sffamily {\smaller REQUIRED}},
% {\sffamily {\smaller SHALL}}, {\sffamily {\smaller SHALL NOT}}, {\sffamily {\smaller SHOULD}},
% {\sffamily {\smaller SHOULD NOT}},
% {\sffamily {\smaller RECOMMENDED}},
% {\sffamily {\smaller MAY}}, and
% {\sffamily {\smaller OPTIONAL}} have a specific
% meaning when shown in {\sffamily {\smaller THIS TYPESTYLE}}, and
% {\sffamily {\smaller MUST}} be interpreted as described in
% RFC 2119 \parencite{rfc2119}.\par
% When shown in normal type, these words keep their conventional
% contextual degree of meaning.\par
% \clearpage
% \section*{Foreword by BV}
% \addcontentsline{toc}{section}{Foreword by BV}
% I have spent many hours admiring colorful bookcases produced by
% Peter Flynn's \emph{bookshelf} package. They helped me to survive
% many boring remote meetings during the {\smaller COVID} pandemic and its
% aftermath. However, since my library had books in different
% languages, I wanted to showcase them as well. I started to write
% patches for the package, and at some point Peter kindly decided to
% transfer the maintenance to me.
%
% I described the project at {\smaller
% TUG}~2024~\parencite{Bookshelf2024}. At present the following
% changes has been implemented:
% \begin{enumerate}
% \item The package now can typeset book spines in any language. It
% automatically selects a random font capable to typeset a given
% spine.
% \item The new |bookshelf-listallfonts| script lists all system and \TeX\
% fonts with ``interesting'' variants, while the new |bookshelf-mkfontsel|
% script populates the |fontsel| directory.
% \item The package now understands fonts in OTF, TTF
% \item The switch from Biber to Bib\TeX\ made the processing much
% faster, and eliminated the need for the separate |entries.tex| file:
% now the |.bbl| file has the right format.
% \item The switch from \emph{fontspec} to primitive font loading also
% made the processing faster---and increased the number of fonts we
% can display.
% \end{enumerate}
%
% There is, however, a price for these improvements: now the package
% is Lua\LaTeX-only.
%
% \bigskip
% \emph{Boris Veytsman, October 2024}
% \clearpage
% \addcontentsline{toc}{section}{Latest changes}
% \section*{Latest changes}
% \subsection*{v.1.0(2025/10/02)}
% New maintainer. Several rewrites.
% \subsection*{v.0.5 (2020-05-24)}
% \paragraph*{Finished initial testing}
% \begin{itemize}
% \item Replaced \textsf{hyperref}
% with \textsf{hypdoc} to avoid
% \emph{makeindex} bug\par
% \end{itemize}
% \subsection*{v.0.1 (2020-05-7)}
% \paragraph*{First packaged draft}
% \begin{itemize}
% \item Done manually from .tex file\par
% \end{itemize}
% \subsection*{v.0.4 (2020-05-19)}
% \paragraph*{Completed documentation}
% \begin{itemize}
% \item Updated note on bug in
% \emph{biber} when processing
% {\ttfamily{}sgml.bib}\par
% \item Removed {\ttfamily{}sgml.bib} as example
% until problems are resolved\par
% \item Backtracked on attempt to use the monographic
% title for articles, chapters, etc\par
% \item Revised notes on production\par
% \end{itemize}
% \subsection*{v.0.3 (2020-05-14)}
% \paragraph*{Finished first pass on documentation}
% \begin{itemize}
% \item Done preliminary testing\par
% \item Script adapted for Mac OS X\par
% \end{itemize}
% \subsection*{Acknowledgments}
% Thanks to many people for the original
% suggestion; and to Isabel Yorke, Bethan Tovey-Walsh,
% Nelson Beebe, The \LaTeX{} Ninja, Stephan Lukasczyk,
% and others for their thesis bibliographies and
% testing comments.\par
% \clearpage
% \section{Documentation}
% During the era of the {\smaller COVID-19} lockdown, the popularity
% of group video messaging grew rapidly, both for business and
% domestic use. As people sought for what they believed to be more
% representative backgrounds than a messy kitchen, an untidy workroom,
% or a sterile blank wall, a well-populated bookshelf was a frequent
% choice.\par
% This package is for those who cannot use (or don't have, or don't
% want to use) such a bookshelf, but can still lay their hands on a
% bibliography or reference list in \BibTeX{} format — perhaps from a
% recent or long-forgotten thesis, book, article, or other
% document.\par
% You also may want to showcase your electronic library. Many
% programs like \emph{Calibre}~\parencite{Calibre} can export the list
% of your electronic books in Bib\TeX\ format. This is how the sample
% library |spines.pdf| was created.\par
% Another important use of this package is to provide a diversion
% during long boring remote meetings. Try to guess the font the given
% spine was typeset with---and use these tiny numbers under the books
% to check your knowledge!
% \par\begingroup
% \fboxsep1em\centering
% \fbox{\begin{minipage}{0.8\columnwidth}\sffamily
% \raggedright\parindent0pt
% \parskip=.5\baselineskip
% \subsubsection*{\sffamily Lua\LaTeX{}}
% To avoid problems with accented
% characters, and to make it easier to maintain,
% this document class uses only Lua\LaTeX.\par
% It will not work with the
% \emph{pdflatex} or \XeTeX.\par
% \end{minipage}}\par\endgroup
% This is a work-in-progress: there are bugs (see \vref{bugs}).\par
% \subsection{What the package does}
% The \textsf{bookshelf} package
% generates what looks like shelves of book spines
% from your list of references, using random
% dimensions (within specified limits) in random but
% contrasting colors, with a randomly-selected
% typeface.\par
% It does this by creating a box (rectangle) for each
% entry in your list, assigning colors to the background and
% foreground, deciding on the layout and font, and then
% stacking the boxes side-by-side as if they were letters on a
% line.\par
% \subsection{Preparation}
% To get things ready for this, you need to install this
% document class, and provide the following data:
% \begin{enumerate}
% \item The list of book as a \BibTeX{} file.
% \item A list of all your usable text fonts and the total number of
% them.
% \item A list of all the colors to choose from.
% \end{enumerate}
% These are explained in more detail in the subsections
% below.\par
% \subsubsection{Your \BibTeX{} file}
% Your \BibTeX{} ({\ttfamily{}.bib}) file,
% suitable for use with \emph{biber}
% rather than \emph{bibtex}.\par
% You may need to replace all the
% old-style symbolic notation accented characters like
% \verb|{\"a}| for
% `ä' and
% \verb|{\l}| for
% `ł'. \par
% If you have a bibliography in
% \emph{EndNote},
% \emph{Mendeley},
% \emph{Zotero},
% \emph{ProCite},
% \emph{Reference Manager},
% etc, you should be able to export it in either
% \BibTeX{} or {\smaller RIS} format. A
% {\smaller RIS} file can easily be
% converted to \BibTeX{} by opening it in
% \emph{JabRef} and saving it
% as \BibTeX{}.\par
% \subsubsection{Font file list}\label{fontfiles}
% A set of 2–line files in a subdirectory called
% |fontsel| representing of all the
% usable text fonts on your system.\par
% Each file {\sffamily {\smaller MUST}} be
% numbered sequentially in its name (eg
% {\ttfamily{}1.tex}, {\ttfamily{}2.tex},
% {\ttfamily{}3.tex}, etc) and
% {\sffamily {\smaller MUST}} contain a |\font| command and define
% the name of the font, for example
% \begin{verbatim}
% \font\SILmfont={[/usr/local/texlive/2024/texmf-dist/fonts/opentype/public/junicode/Junicode-SmCondMediumItalic.otf]:+clig;+liga;+tlig;+swsh}\SILmfont
% \def\SILmfontname{Junicode SmCond Medium Italic; Swash}%
% \end{verbatim}
% This list can be created using the scripts |bookshelf-listallfonts| and
% |bookshelf-mkfontsel|, see~\vref{sec:scripts}.
% \subsubsection{Maximum number of fonts}
% A file called {\ttfamily{}pickfont.tex}
% containing a
% \verb|\setcounter{SIL@maxfont}{...}| command to
% set the total number of the fonts which are represented in
% the {\ttfamily{}fontsel} subdirectory above\par
% This file can be created using the scripts |bookshelf-listallfonts| and
% |bookshelf-mkfontsel|, see~\vref{sec:scripts}.
% \subsubsection{List of colors}
% A list of all the colors represented by the
% {\smaller SVG} palette used by the
% \textsf{xcolor} package: the file is called
% called {\ttfamily{}bookshelf-svgnam.tex}.
% This contains three definitions:\par
% \begin{enumerate}
% \item the command {\ttfamily{}\textbackslash{}SIL@svgcolname}
% which uses an {\ttfamily{}\textbackslash{}ifcase} command to
% return the name of the \emph{n}th color
% in alphabetical order;\par
% \item the command {\ttfamily{}\textbackslash{}SIL@svgcolval} which
% does the same to return the brightness value of that
% color, computed by the formula on \vpageref{bright} (see script for
% details);\par
% \item the counter {\ttfamily{}SIL@maxcolno} which holds
% the number of colors available.\par
% \end{enumerate}
% This file is included in the distribution.
%
% In the previous versions of the ditribution it was created with the
% from |svgnam.def| database. The script |svgnam.sh| is retained in
% the distribution and can be used to recreate the file.
%
% \subsection{Producing your bookshelf}
%
% \subsubsection{Producing the list of fonts}
% \label{sec:scripts}
%
% Each system has its own fonts installed, so you need to create the
% list of fonts installed on \emph{your} system. It is done in three
% steps.
% \begin{enumerate}
% \item Update the database of fonts known to Lua\TeX:
% \begin{verbatim}
% luaotfload-tool --update --force
% \end{verbatim}
% The key |--force| forces the update even if Lua\TeX\ thinks it is
% not necessary: sometimes it is mistaken.
% \item Create the list of the usable fonts and font variants:
% \begin{verbatim}
% bookshelf-listallfonts [options] > allfonts
% \end{verbatim}
% The script lists all fonts in {\smaller OTF, TTF} or {\smaller TTC}
% format, known to Lua\LaTeX. For scripts in {\smaller OTF} and
% {\smaller TTF} format it looks at the ``interesting'' Open Type
% features like swash and stylistic variant and lists them too. This
% means that the bookshelf might have spines typeset in the different
% variants of the same font---they are considered different fonts!
% You can change the list of feaures using the key |-f FEATURES_FILE|;
% see the |doc| directory for an example. The script tries to exclude
% broken font files; you can change the list with the key
% |-x EXCLUDED_PATTERNS|. Again, there is an example in the |doc|
% directory.
% \item Create the |fontsel| directory and the file |pickfont.tex|
% using the command
% \begin{verbatim}
% bookshelf-mkfontsel allfonts
% \end{verbatim}
% \end{enumerate}
%
% \subsubsection{Driver file}
%
% The distribution contains the file |spines.tex|
% \begin{verbatim}
% % !TEX TS-program = lualatex
% % !TEX encoding = UTF-8 Unicode
% % !BIB TS-program = bibtex
% \documentclass[landscape]{bookshelf}
% \begin{document}
% \nocite{*}
% \bibliography{sample}
% \bibliographystyle{bookshelf}
% \end{document}
% \end{verbatim}
%
% Change |sample| to the name of your bibliography, and typeset the
% file using |lualatex| and | bibtex|.
%
% You should see your books nicely placed on the shelves. The small
% numbers under each book are meaningful: they are the line numbers in
% the |allfonts| file. You may use them if you play ``Guess the
% font'' game.
%
% \subsubsection{Options}
% The class comes set for making an
% \textbf{\texttt{a0paper}} page (1189 mm × 841 mm
% or 4′ 11″ × 2′ 10″) in
% \textbf{\texttt{landscape}} mode, suitable for
% large bibliographies. If you have a smaller
% {\ttfamily{}.bib} file, or if you want
% fewer volumes per page, you can change the paper
% size option in the
% {\ttfamily{}\textbackslash{}documentclass} command to a
% smaller one: all the `A'
% sizes from 5 to 0 are supported, plus the common
% US office sizes including Ledger (Tabloid).\par
% There is also a \textbf{\texttt{portrait}} option to
% produce the page in that format instead of
% landscape.\par
%
% \subsection{Bugs}\label{bugs}
% Some things don't yet work as they should, and
% there are some features that may or may not make
% the final cut. Please report bugs at
% \url{
https://github.com/borisveytsman/bookshelf}\par
%
%
% \StopEventually{\label{endcode}%
% \clearpage
% \newgeometry{left=3cm}%
% \addcontentsline{toc}{section}{Change History}%
% \label{changehistory}%
% \PrintChanges
% \clearpage
% \label{codeindex}%
% \addcontentsline{toc}{section}{Index}%
% \PrintIndex}
% \addtolength{\CPKrevmarg}{\widthof{\LabelFont{AddToShipoutPictureBG}}}
% \newgeometry{left=\CPKrevmarg}
% \message{Margin reset to \the\CPKrevmarg, to fit <AddToShipoutPictureBG>}
% \iffalse
%<*class>
% \fi
% \clearpage
% \section{Implementation}\label{setup}
% \par
% \subsection{Auto-initialisation}\label{setup:autoinit}
% This section is added automatically by \textit{ClassPack}
% as a preamble to all classes and style packages.
% The \textsf{fixltx2e} package, which used to be included
% automatically, is no longer preloaded, as its
% features are now a part of the latest \LaTeXe\ kernel.\par
% The code starts with identity and requirements which are
% generated automatically as needed by the Doc\TeX\ system.
% For details see the \textsf{ltxdoc} package documentation.
% \par\smallskip
% \begingroup\color{DarkRed}\footnotesize
% \leavevmode\enspace{\scriptsize1}\quad{\ttfamily\textbackslash NeedsTeXFormat\{LaTeX2e\}[2017/04/15]}\\
% \leavevmode\enspace{\scriptsize2}\quad{\ttfamily\textbackslash ProvidesClass\{bookshelf\}[2020/05/24 v0.5}\\
% \leavevmode\enspace{\scriptsize3}\qquad{\ttfamily Turn your bibliography into a bookshelf image]}\\\endgroup
% \setcounter{CodelineNo}{3}
% \begin{CPK@package}{fix-cm}
% Preloaded functions to override the default \LaTeX\
% step-size font sizes (which can still be used,
% but are no longer restrictions).\par
% \begin{macrocode}
\RequirePackage{fix-cm}
% \end{macrocode}
% \end{CPK@package}
% \begin{CPK@option}{svgnames}
% Pass the \textbf{\texttt{svgnames}} option to the
% \textsf{xcolor} package if that gets loaded later.
% This avoids a conflict with any other packages
% (eg \textsf{hyperref}) which use their own default
% is when they load \textsf{xcolor}.\par
% \begin{macrocode}
\PassOptionsToPackage{svgnames}{xcolor}
% \end{macrocode}
% \end{CPK@option}
% \subsection{Options}\label{options}
% \iffalse
%%
%% ******************************************************************
%%
%% Options
% \fi
% The paper size and orientation are the only two valid
% options, both of which are the same as the standard
% documentclass options, and will be passed to the underlying
% class automatically, but they need recording so that they
% can be used by the \textsf{geometry}
% package. The default is for A0 paper, landscape.\par
% \begin{macrocode}
\def\SIL@paper{a0paper}%
\DeclareOption{a0paper}{%
\def\SIL@paper{a0paper}%
\setlength\paperheight {1189mm}%
\setlength\paperwidth {841mm}}
\DeclareOption{a1paper}{%
\def\SIL@paper{a1paper}%
\setlength\paperheight {841mm}%
\setlength\paperwidth {594mm}}
\DeclareOption{a2paper}{%
\def\SIL@paper{a2paper}%
\setlength\paperheight {594mm}%
\setlength\paperwidth {420mm}}
\DeclareOption{a3paper}{%
\def\SIL@paper{a3paper}%
\setlength\paperheight {420mm}%
\setlength\paperwidth {297mm}}
\DeclareOption{a4paper}{%
\def\SIL@paper{a4paper}%
\setlength\paperheight {297mm}%
\setlength\paperwidth {210mm}}
\DeclareOption{a5paper}{%
\def\SIL@paper{a5paper}%
\setlength\paperheight {210mm}%
\setlength\paperwidth {148mm}}
\DeclareOption{b5paper}{%
\def\SIL@paper{b5paper}%
\setlength\paperheight {250mm}%
\setlength\paperwidth {176mm}}
\DeclareOption{letterpaper}{%
\def\SIL@paper{letterpaper}%
\setlength\paperheight {11in}%
\setlength\paperwidth {8.5in}}
\DeclareOption{legalpaper}{%
\def\SIL@paper{legalpaper}%
\setlength\paperheight {14in}%
\setlength\paperwidth {8.5in}}
\DeclareOption{executivepaper}{%
\def\SIL@paper{executivepaper}%
\setlength\paperheight {10.5in}%
\setlength\paperwidth {7.25in}}
\DeclareOption{ledgerpaper}{%
\def\SIL@paper{ledgerpaper}%
\setlength\paperheight {17in}%
\setlength\paperwidth {11in}}
\DeclareOption{tabloidpaper}{%
\def\SIL@paper{tabloidpaper}%
\setlength\paperheight {17in}%
\setlength\paperwidth {11in}}
\def\SIL@orient{landscape}%
\DeclareOption{landscape}{%
\def\SIL@orient{landscape}%
\setlength\@tempdima {\paperheight}%
\setlength\paperheight {\paperwidth}%
\setlength\paperwidth {\@tempdima}}
\DeclareOption{portrait}{%
\def\SIL@orient{}}
% \end{macrocode}
% \subsection{Load the document base class}\label{classload}
% \iffalse
%%
%% ******************************************************************
%%
%% Load the document base class
% \fi
% This class is based on the standard \LaTeX{}
% \DescribeClass{report}\textsf{report} class, with no special options
% except the extra sizes defined above. The default is A0
% paper, landscape.\par
% \begin{macrocode}
\DeclareOption*{\ClassWarning{bookshelf}{%
Unknown option `\CurrentOption', please RTFM}}
\ProcessOptions\relax
\LoadClass{report}
% \end{macrocode}
%\iffalse
%%
%% Packages required for the class or package
%%
% \fi
% \subsection{Packages required for the class or
% package}\label{clspackages}
% \begin{CPK@package}{fontspec}
% Font specification setup for use with \XeLaTeX{}.
% \iffalse
%% Font specification setup for use with \XeLaTeX{}.
% \fi
% \begin{macrocode}
\RequirePackage{fontspec}%
% \end{macrocode}
% \end{CPK@package}
% \begin{CPK@package}{calc}
% Required for calculations involving lengths or counters,
% such as changes to widths for margin adjustment.
% \iffalse
%% Required for calculations involving lengths or counters, such as changes to widths for margin adjustment.
% \fi
% \begin{macrocode}
\RequirePackage{calc}%
% \end{macrocode}
% \end{CPK@package}
% \begin{CPK@package}{fp}
% Used for fixed-point calculations;
% \iffalse
%% Used for fixed-point calculations
% \fi
% \begin{macrocode}
\RequirePackage{fp}%
% \end{macrocode}
% \end{CPK@package}
% \begin{CPK@package}{graphicx}
% Provide for graphics (PNG, JPG, or PDF format (only) for
% pdflatex; EPS format (only) for standard \LaTeX{}).
% \iffalse
%% Provide for graphics (PNG, JPG, or PDF format (only) for pdflatex; EPS format (only) for standard \LaTeX{}).
% \fi
% \begin{macrocode}
\RequirePackage{graphicx}%
% \end{macrocode}
% \end{CPK@package}
% \begin{CPK@package}{xcolor}
% Provide color.
% \iffalse
%% Provide color.
% \fi
% \begin{macrocode}
\RequirePackage{xcolor}%
\@ifundefined{T}{%
\newcommand{\T}[2]{{\fontencoding{T1}%
\selectfont#2}}}{}
% \end{macrocode}
% There seems to be a bug in the T1 encoding of some package
% (unidentified, but possibly \textsf{xcolor}) which
% uses the command {\ttfamily{}\textbackslash{}T1}, which is an
% impossibility (no digits allowed in command names). So we fake
% it here to stop \LaTeX{} complaining, by dropping the first
% argument on the floor.
% \end{CPK@package}
% \begin{CPK@package}{eso-pic}
% Add picture commands (or backgrounds) to every page.
% \iffalse
%% Add picture commands (or backgrounds) to every page.
% \fi
% \begin{macrocode}
\RequirePackage{eso-pic}%
% \end{macrocode}
% \end{CPK@package}
% \begin{CPK@package}{geometry}
% Package for establishing margins and text area.
% \iffalse
%% Package for establishing margins and text area.
% \fi
% \begin{macrocode}
\RequirePackage[\SIL@paper,\SIL@orient,nohead,
nofoot,margin=1cm]{geometry}%
% \end{macrocode}
% \end{CPK@package}
%
% \subsection{Non-package resources}
% \iffalse
%%
%% ******************************************************************
%%
%% Non-package resources
% \fi
% \begin{CPK@file}{random.tex}\label{file--random.tex}
% There is one resource not available in packaged form,
% the module that lets \LaTeX{} create random values. This is
% in {\ttfamily{}random.tex}, which on the author's
% system is hiding in a directory
% {\ttfamily{}texmf/tex/generic/genmisc/}, in the
% {\ttfamily{}texmf-dist} tree, and indexed by an
% {\ttfamily{}ls-R} database, so it should therefore
% be findable by any \TeX{} system.\par
% \begin{macrocode}
\input{random.tex}
% \end{macrocode}
% \end{CPK@file}
% \subsection{The code}
% \iffalse
%%
%% ******************************************************************
%%
%% The code
% \fi
% This is beta software: the code is messy and covered in
% tracing output.\par
% \subsubsection{Font selection}\label{fonts}
% \begin{CPK@counter}{maxfont}\label{counter--maxfont}
% This is set in the {\ttfamily{}\textbackslash{}input} file
% {\ttfamily{}pickfont.tex}, which is created by
% the preparatory data script
% {\ttfamily{}prepdata.sh}. It is the number of
% working text fonts found on the system.\par
% \begin{macrocode}
\newcounter{SIL@maxfont}
% \end{macrocode}
% \end{CPK@counter}
% \begin{CPK@counter}{SIL@fontsel}\label{counter--SIL@fontsel}
% This is set to a random number between one and
% \DescribeCounter{SIL@maxfont}{\ttfamily{}SIL@maxfont}, and used as the
% name of the file containing the font name.\par
% \begin{macrocode}
\newcounter{SIL@fontsel}
% \end{macrocode}
% \end{CPK@counter}
% \begin{CPK@file}{pickfont.tex}\label{file--pickfont.tex}
% This file is created by the preparatory data script
% {\ttfamily{}prepdata.sh} after it sets up the
% subdirectory list of valid text fonts. It sets the value
% of \DescribeCounter{SIL@maxfont}{\ttfamily{}SIL@maxfont}.\par
% \begin{macrocode}
\input{pickfont.tex}
% \end{macrocode}
% \end{CPK@file}
% \subsubsection{Color selection}\label{color}
% \begin{CPK@counter}{SIL@maxcolno}\label{counter--SIL@maxcolno}
% This value is set at the end of the file
% {\ttfamily{}bookshelf-svgnam.tex}. This is the number of
% color names found by the routine in
% {\ttfamily{}prepdata.sh} which extracts the color
% names.\par
% \begin{macrocode}
\newcounter{SIL@maxcolno}
% \end{macrocode}
% \end{CPK@counter}
% \begin{CPK@file}{bookshelf-svgnam.tex}\label{file--bookshelf-svgnam.tex}
% The preparatory data script
% {\ttfamily{}prepdata.sh} retrieves the colors named
% in the \textbf{\texttt{svgnames}} option to the
% \textsf{xcolor} package and instantiates them
% as a \LaTeX{} {\ttfamily{}\textbackslash{}ifcase} list in the file
% {\ttfamily{}bookshelf-svgnam.tex} as the command
% {\ttfamily{}\textbackslash{}SIL@svgcolname}.\par
% \begin{macrocode}
\input{bookshelf-svgnam.tex}
% \end{macrocode}
% \end{CPK@file}
% \begin{CPK@counter}{SIL@loopcount}\label{counter--SIL@loopcount}
% The random font selection is done in a loop because
% of the need to test the values. This counter counts the
% iterations…\par
% \begin{macrocode}
\newcounter{SIL@loopcount}
% \end{macrocode}
% \end{CPK@counter}
% \begin{CPK@counter}{SIL@maxloop}\label{counter--SIL@maxloop}
% …and this one the limit.\par
% \begin{macrocode}
\newcounter{SIL@maxloop}
% \end{macrocode}
% \end{CPK@counter}
% \begin{CPK@counter}{SIL@bgcolno}\label{counter--SIL@bgcolno}
% The colors are selected numerically. This value is
% the background color of the spine of a book.\par
% \begin{macrocode}
\newcounter{SIL@bgcolno}
% \end{macrocode}
% \end{CPK@counter}
% \begin{CPK@counter}{SIL@fgcolno}\label{counter--SIL@fgcolno}
% And this is the foreground color, used to typeset
% the title and author on the spine of a book.\par
% \begin{macrocode}
\newcounter{SIL@fgcolno}
% \end{macrocode}
% \end{CPK@counter}
% \begin{CPK@length}{\splitpoint}\label{length--splitpoint}
% To make sure that \DescribeCounter{SIL@bgcolno}{\ttfamily{}SIL@bgcolno} and \DescribeCounter{SIL@fgcolno}{\ttfamily{}SIL@fgcolno}
% are distinct, we will need to pick one
% `dark' and one
% `light', crudely distinguished by
% examining their `brightness'
% (monochrome intensity value) using the formula
% \label{bright}\(b=\sqrt(.241r^2+.691g^2+.068b^2)\) due to \href{
https://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx}{Nir
% Dobovizki}. From inspection, the modal point of
% the {\smaller SVG} values occurs around 0.6, so
% use use this to determine if the randomly-selected color
% is `dark' or
% `light'. Because it's a decimal
% fraction, we express it as a dimension and strip off the
% `pt' later.\par
% \begin{macrocode}
\newlength{\SIL@splitpoint}
\setlength{\SIL@splitpoint}{0.6pt}
% \end{macrocode}
% \end{CPK@length}
% \begin{CPK@macro}{\SIL@bgcol}\label{macro--SIL@bgcol}
% We establish defaults for the background color…\par
% \begin{macrocode}
\def\SIL@bgcol{White}
% \end{macrocode}
% \end{CPK@macro}
% \begin{CPK@macro}{\SIL@fgcol}\label{macro--SIL@fgcol}
% …and the foreground color.\par
% \begin{macrocode}
\def\SIL@fgcol{Black}
% \end{macrocode}
% \end{CPK@macro}
% \begin{CPK@length}{\SIL@bgval}\label{length--SIL@bgval}
% The values computed by the
% {\ttfamily{}prepdata.sh} script and stored in
% {\ttfamily{}bookshelf-svgnam.tex} are decimal fractions,
% to they need to be retrieved as lengths. This is the
% background value…\par
% \begin{macrocode}
\newlength{\SIL@bgval}
% \end{macrocode}
% \end{CPK@length}
% \begin{CPK@length}{\SIL@fgval}\label{length--SIL@fgval}
% …and the foreground value.\par
% \begin{macrocode}
\newlength{\SIL@fgval}
% \end{macrocode}
% \end{CPK@length}
% \begin{CPK@length}{\SIL@bgfgdiff}\label{length--SIL@bgfgdiff}
% The `dark' or
% `light' test discussed above also
% needs to test if the values are too close to the
% splitpoint. By examination, if the values have an
% absolute difference of 0.2 they should be visually
% distinct enough. The difference is calculated and stored
% in this length variable, as it's a decimal fraction.\par
% \begin{macrocode}
\newlength{\SIL@bgfgdiff}
% \end{macrocode}
% \end{CPK@length}
% \begin{CPK@switch}{\SIL@notyetcols}\label{switch--SIL@notyetcols}
% In the testing for colors, the nested conditionals
% set this switch true or false, so that it can be used to
% control the iteration through successive attempts to find
% suitable random values.\par
% \begin{macrocode}
\newif\ifSIL@notyetcols
% \end{macrocode}
% \end{CPK@switch}
% \subsubsection{Page border setup}\label{borders}
% \begin{CPK@macro}{\AddToShipoutPictureBG}\label{macro--AddToShipoutPictureBG}
% The page background color is set to a pale brown
% roughly matching the pine veneer of IKEA bookcases, with
% the inner page (behind the books) in a dark shadow
% brown. The technique for imposing a colored margin is
% due to \href{
https://tex.stackexchange.com/questions/7725/how-to-set-a-certain-color-other-than-white-to-margin-areas}{Ulrike
% Fischer} and uses the commands from the
% \textsf{eso-pic} package.\par
% \begin{macrocode}
\pagecolor{BurlyWood}
\AddToShipoutPictureBG{%
\AtTextLowerLeft{\color{SaddleBrown}%
\rule[-\footskip]{\textwidth}{%
\dimexpr\textheight+\footskip}}}
% \end{macrocode}
% \end{CPK@macro}
% \subsubsection{Size and shape}\label{sizeshape}
% Each book is assigned a random height and width,
% within the bounds set by the maxima and minima. The final
% dimensions may then be modified by the choice of layout
% and font.\par
% \begin{macrocode}
\newlength{\SIL@bookheight}
\newlength{\SIL@bookwidth}
\newlength{\SIL@minbookwidth}
\newlength{\SIL@maxbookwidth}
\newlength{\SIL@minbookheight}
\newlength{\SIL@maxbookheight}
% \end{macrocode}
% \subsubsection{Title and author dimensions}\label{titling}
% The title and author need to be measured, and
% decisions are made about what size they need to be. The
% two layouts (author separately at the top, and author
% inline to title) are distinguished with the
% {\ttfamily{}\textbackslash{}SIL@topauthor} conditional. If the title
% (with or without the author can fit on one line (rather
% than multiple lines) this is signalled with the
% {\ttfamily{}\textbackslash{}SIL@titleoneline} conditional.\par
% \begin{macrocode}
\newlength{\SIL@titlewidth}
\newlength{\SIL@authorwidth}
\newlength{\SIL@titleheight}
\newlength{\SIL@authorheight}
\newlength{\SIL@scaledtitle}
\newlength{\SIL@heightfortitle}
\newbox\SIL@titlebox
\newif\ifSIL@topauthor
\newif\ifSIL@titleoneline
% \end{macrocode}
% \subsubsection{Handling the math}
% \begin{CPK@counter}{SIL@scale}\label{counter--SIL@scale}
% To extract the integer part of a fixed-point value,
% we define a simple strip which uses the integer and
% throws away the rest. The integer ends up in this
% counter.\par
% \begin{macrocode}
\newcounter{SIL@scale}
% \end{macrocode}
% \end{CPK@counter}
% \begin{CPK@macro}{\SIL@scaleint}\label{macro--SIL@scaleint}
% The integer macro returns the counter above.\par
% \begin{macrocode}
\def\SIL@scaleint#1.#2\sentinel{%
\setcounter{SIL@scale}{#1}}
% \end{macrocode}
% \end{CPK@macro}
% \subsubsection{Settings}
% We set the space around a box and the thickness of the
% rule, and remove the page numbers.\par
% \begin{macrocode}
\fboxsep1em\fboxrule.1pt
\pagestyle{empty}
% \end{macrocode}
%
% \subsubsection{Auxillary macro: fitting text in a box}
%
% \begin{CPK@macro}{\SIL@fittext}\label{macro--SIL@fittext}
% For typesetting title we use an auxillary macro |\SIL@fittext|. It
% has four parameters: the text to be typeset, the width ($W$), the
% height $H$, and the box $W\times H$ to put the text into. We want
% to get the maximal font size that still fits in the box.
% Unfortunately there is a limitation on the maximal number of fonts
% \TeX\ can handle (currently 9000 by default). Since each size
% change counts as a new font, things can quickly go out of hand.
% Therefore instead of scaling the font we scale the box.
%
% So our aim is to find the maximal scaling factor $S$ such as (1)~the
% text is typeset in a $w\times h$ box, (2)~the text box scales to the
% given width, $W=Sw$, (3)~the text box does not overflow the height,
% $H\le Sh$.
%
% The algorithm is the following:
% \begin{enumerate}
% \item If the text fits in one line, we expand the box for the line
% to occupy $W$, setting $S=W/w$.
% \item Otherwise, we try to typeset the text in the box of horizontal
% size $W$ ($S=1$) and calculate box height $h$. We determine how
% much we can expand or shrink the box, setting $S=H/h$.
% \item We typeset the text in the box of width $w=W/S$.
% \item Due to changed line breaks its height $h$ might be higher than
% $H/S$. In this case we start to decrease $S$ by 5\% on each step
% and repeat typesetting until $w\le W/S$
% \end{enumerate}
%
% Now, the implementation.
%
% First, we calculate $W$ and $H$ by stripping the pt dimension
% \begin{macrocode}
\def\SIL@fittext#1#2#3#4{%
\@tempdima=#2\relax
\edef\SIL@W{\strip@pt\@tempdima}%
\@tempdima=#3\relax
\edef\SIL@H{\strip@pt\@tempdima}%
% \end{macrocode}
% Try to set up the text in one line
% \begin{macrocode}
\setbox#4=\hbox{\raggedright\noindent#1}%
\@tempdima=\wd#4\relax
\edef\SIL@w{\strip@pt\@tempdima}%
\ifdim#2>\@tempdima\relax
\FPeval\SIL@S{\SIL@W/\SIL@w}%
\typeout{Text fits in one line: have H=\SIL@w pt, want \SIL@W pt}%
\typeout{Trying S=\SIL@S}%
\else
% \end{macrocode}
% We start with the scale factor $S=1$. We add |\vskip0pt| to the
% text to set the box depth to zero.
% \begin{macrocode}
\typeout{Text does not fit in one line}%
\def\SIL@S{1}%
\FPeval\SIL@w{\SIL@W/\SIL@S}%
\setbox#4=\vbox{\hsize=\SIL@w pt\relax
\raggedright\noindent#1\vskip0pt}%
\@tempdima=\ht#4\relax
\edef\SIL@h{\strip@pt\@tempdima}%
\@tempdima = \SIL@S \@tempdima\relax
\typeout{Trying S=\SIL@S. Got H=\the\@tempdima. Want \SIL@H pt}%
\FPeval\SIL@S{\SIL@H/\SIL@h}%
\fi
% \end{macrocode}
% Rescaling the box for the first time. If $S$ on the previous step
% is below 1, start again with 1.
% \begin{macrocode}
\FPmax\SIL@S\SIL@S{1}%
\FPeval\SIL@w{\SIL@W/\SIL@S}%
\setbox#4=\vbox{\hsize=\SIL@w pt\relax
\raggedright\noindent#1\vskip0pt}%
\@tempdima=\ht#4\relax
\edef\SIL@h{\strip@pt\@tempdima}%
\@tempdima = \SIL@S \@tempdima\relax
\typeout{Trying S=\SIL@S. Got H=\the\@tempdima. Want \SIL@H pt}%
% \end{macrocode}
% If the text does not fit, keep reducing it by 5\% at a type
% \begin{macrocode}
\ifdim\@tempdima>#3\relax
\loop
\FPeval\SIL@S{0.95*\SIL@S}%
\FPeval\SIL@w{\SIL@W/\SIL@S}%
\setbox#4=\vbox{\hsize=\SIL@w pt\relax
\raggedright\noindent#1\vskip0pt}%
\@tempdima=\ht#4\relax
\edef\SIL@h{\strip@pt\@tempdima}%
\@tempdima = \SIL@S \@tempdima\relax
\typeout{Trying S=\SIL@S. Got H=\the\@tempdima. Want \SIL@H pt}%
\ifdim\@tempdima>#3\repeat
\fi
% \end{macrocode}
% And the final typesetting
% \begin{macrocode}
\setbox#4=\vbox to #3{\hsize=#2\relax
\vfill
\noindent
\scalebox{\SIL@S}{\vbox{\hsize=\SIL@w pt\relax
\raggedright\noindent#1\vskip0pt}}%
\vfill}%
}
% \end{macrocode}
%
% \end{CPK@macro}
%
%
% \subsubsection{Selecting the font for the book}\label{fontsel}
%
% In a multilingual library some books can be typeset only in specific
% fonts. Here we randomly select a font to typeset the given book.
%
% We define a macro that checks whether the given string can be
% typeset in the font just defined by fontspec.
%
% We write the program in expl3 syntax because it has nice mapping
% subroutines and becasue fontspec internal variables are in expl3.
%
% \begin{macrocode}
\ExplSyntaxOn
% \end{macrocode}
% An auxillary routine checking whether the character can be typeset
% with the current font. Copied from fontspec internals
% \begin{macrocode}
\prg_new_conditional:Nnn \__SIL_primitive_font_glyph_if_exists:n {TF,F}
{
\tex_iffontchar:D \SILmfont `#1 \scan_stop:
\prg_return_true:
\else:
\prg_return_false:
\fi:
}
% \end{macrocode}
% And the document command
% \begin{macrocode}
\prg_new_conditional:Nnn \__SIL_can_typeset:n {TF}
{
\typeout{Trying ~ to ~ typeset ~ #1}
\bool_set_true:N \l_tmpa_bool
\str_map_inline:nn {#1} {
\__SIL_primitive_font_glyph_if_exists:nTF {##1} {}{
\bool_set_false:N \l_tmpa_bool
\typeout{Cannot ~ typeset ~ ##1}
\str_map_break:
}
}
\bool_if:nTF \l_tmpa_bool {\prg_return_true:} {\prg_return_false:}
}
\cs_generate_variant:Nn \__SIL_can_typeset:nTF {x}
\NewDocumentCommand\CanTypesetTF { m m m}{
\__SIL_can_typeset:xTF{#1}{#2}{#3}
}
\ExplSyntaxOff
% \end{macrocode}
%
% We define some counters and flags for the font selection
% \begin{macrocode}
\def\SIL@maxfonttries{100}
\newif\ifSIL@fontfound
% \end{macrocode}
%
%
% Another twist is that we cannot have too many fonts used. Therefore
% we add all fontsel files to a stack, and after having
% 2100 of them, we reuse opened files. Again, it is easy to do in
% expl3.
% \begin{macrocode}
\ExplSyntaxOn
\seq_new:N \l__SIL_fontstack
\NewDocumentCommand\AddFontToStack {m} {%
\seq_gput_right:Ne \l__SIL_fontstack {#1}
}
\NewDocumentCommand\ReuseFont {} {
\seq_rand_item:N \l__SIL_fontstack
}
\ExplSyntaxOff
\newcount\SIL@num@fontsel@files
\SIL@num@fontsel@files=0
\def\SIL@max@fontsel@files{5500}
% \end{macrocode}
%
% \subsubsection{Making the book}\label{mb}
% The {\ttfamily{}\textbackslash{}makebook} macro is huge, and
% handles all the detail of making a book spine. It takes
% two mandatory arguments: the author and the title of the
% book.\par
% \begin{CPK@macro}{\makebook}\label{macro--makebook}
% Start by announcing the entry label and setting the
% values that need to be reset every time.\par
% \begin{macrocode}
\newcommand{\makebook}[2]{%
\typeout{^^JTypesetting #1---#2}%
\setcounter{SIL@maxloop}{10}%
\setcounter{SIL@loopcount}{0}%
% observed
\setlength{\SIL@minbookwidth}{5mm}%
\setlength{\SIL@maxbookwidth}{20mm}%
% A5 to A4 height
\setlength{\SIL@minbookheight}{70mm}%
\setlength{\SIL@maxbookheight}{110mm}%
\setlength{\SIL@bookwidth}{0pt}%
\setlength{\SIL@bookheight}{0pt}%
\setlength{\SIL@heightfortitle}{0pt}%
\SIL@topauthorfalse
% \end{macrocode}
% \end{CPK@macro}
% \begin{CPK@macro}{\loop}\label{macro--loop}
% Start a loop which will pick two random integers,
% one for background and one for foreground colors. Look
% these up in the {\ttfamily{}\textbackslash{}SIL@svgcolval} (in
% {\ttfamily{}bookshelf-svgnam.tex}) to get the brightness
% values, and calculate the absolute distance between
% them.\par
% \begin{macrocode}
\loop
\addtocounter{SIL@loopcount}{1}%
\typeout{Try \theSIL@loopcount}%
\setrannum{\c@SIL@bgcolno}{1}{%
\c@SIL@maxcolno}%
\typeout{BG=\theSIL@bgcolno}%
\setrannum{\c@SIL@fgcolno}{1}{%
\c@SIL@maxcolno}%
\typeout{FG=\theSIL@fgcolno}%
\setlength{\SIL@bgval}{%
\SIL@svgcolval{\theSIL@bgcolno}pt}%
\typeout{BGval=\the\SIL@bgval}%
\setlength{\SIL@fgval}{%
\SIL@svgcolval{\theSIL@fgcolno}pt}%
\typeout{FGval=\the\SIL@fgval}%
\setlength{\SIL@bgfgdiff}{%
\SIL@bgval - \SIL@fgval}%
\typeout{Split gap is \the\SIL@bgfgdiff}%
\ifdim\SIL@bgfgdiff<0pt
\setlength{\SIL@bgfgdiff}{%
\SIL@fgval - \SIL@bgval}%
\typeout{Using absolute value
\the\SIL@bgfgdiff}%
\fi
% \end{macrocode}
% The colours need to be separated either side of the
% 0.6 splitpoint value of the calculated brightness, so
% make this the outer test, and make the inner test for
% the separation difference. This will return true if the
% colors are separated enough, and come from opposite
% sides of the split point. If the loop makes \DescribeCounter{SIL@maxloop}{\ttfamily{}SIL@maxloop}
% iterations without finding a pair of values, use
% the default white on black.\par
% \begin{macrocode}
\ifdim\SIL@bgval<\SIL@splitpoint
\ifdim\SIL@fgval>\SIL@splitpoint
\ifdim\SIL@bgfgdiff>0.2pt
\SIL@notyetcolsfalse
\else
\SIL@notyetcolstrue
\fi
\else
\SIL@notyetcolstrue
\fi
\else
\ifdim\SIL@fgval<\SIL@splitpoint
\ifdim\SIL@bgfgdiff>0.2pt
\SIL@notyetcolsfalse
\else
\SIL@notyetcolstrue
\fi
\else
\SIL@notyetcolstrue
\fi
\fi
\typeout{BG=\theSIL@bgcolno,
FG=\theSIL@fgcolno}%
\ifnum\c@SIL@loopcount>\c@SIL@maxloop
\SIL@notyetcolsfalse
\fi
\ifSIL@notyetcols\repeat
\def\SIL@bgcol{\SIL@svgcolname{%
\theSIL@bgcolno}}%
\def\SIL@fgcol{\SIL@svgcolname{%
\theSIL@fgcolno}}%
\ifnum\c@SIL@loopcount>\c@SIL@maxloop
\typeout{Using default colors after \the\c@SIL@maxloop\space attempts}%
\def\SIL@bgcol{Black}%
\def\SIL@fgcol{White}%
\fi
\typeout{BG=\SIL@bgcol, FG=\SIL@fgcol}%
% \end{macrocode}
% Now pick a random font: the files generated by
% {\ttfamily{}prepdata.sh} are named as integers with
% a {\ttfamily{}.tex} extension in the
% {\ttfamily{}fontsel} directory. These files load
% the font as {\ttfamily{}\textbackslash{}SILmfont} (no
% {\ttfamily{}@} sign, because this is
% occurring in user mode), and define
% {\ttfamily{}\textbackslash{}SILmfontname} as the name (for the
% same reason).\par
% \begin{macrocode}
\c@SIL@loopcount=1\relax
\loop
\ifnum\SIL@num@fontsel@files<\SIL@max@fontsel@files
\advance\SIL@num@fontsel@files by 1\relax
\typeout{Opening new fontsel file, counter=\the\SIL@num@fontsel@files}%
\setrannum{\c@SIL@fontsel}{1}{\c@SIL@maxfont}%
\AddFontToStack{\the\c@SIL@fontsel}%
\else
\typeout{Reusing fontsel file}%
\expandafter\c@SIL@fontsel\ReuseFont\relax
\fi
\input{fontsel/\
[email protected]}\unskip%
\typeout{Trying \SILmfontname, attempt \the\c@SIL@loopcount}%
\CanTypesetTF{#2---#1}{\global
\SIL@fontfoundtrue}{\global
\SIL@fontfoundfalse}%
\ifSIL@fontfound
\c@SIL@loopcount=\SIL@maxfonttries\relax
\else
\addtocounter{SIL@loopcount}{1}%
\fi
\ifnum\c@SIL@loopcount<\SIL@maxfonttries\repeat
\ifSIL@fontfound
\typeout{Set in \SILmfontname}%
% \end{macrocode}
%
%
% Measure the author width and height at the default
% size (10pt). If the author fits in 90\% of the
% maximum width of the book, we put it at the top of the
% spine and shrink the book width to 1.1 times the set
% width, provided that is not less than the defined
% minimum width. The book width is therefore fixed at this
% point and won't change later.\par
% \begin{macrocode}
\settowidth{\SIL@authorwidth}{%
\SILmfont#1}%
\typeout{Author width: \the\SIL@authorwidth}%
\settoheight{\SIL@authorheight}{%
\SILmfont#1}%
\typeout{Author height: \the\SIL@authorheight}%
\ifdim\SIL@authorwidth<.9\SIL@maxbookwidth
\typeout{Author width is less than 90\%
of \the\SIL@maxbookwidth}%
\setlength{\SIL@bookwidth}{%
1.1\SIL@authorwidth}%
\typeout{Book width set to \the\SIL@bookwidth}%
\ifdim\SIL@bookwidth<\SIL@minbookwidth
\setlength{\SIL@bookwidth}{%
\SIL@minbookwidth}%
\typeout{Book width reset to min
\the\SIL@minbookheight}%
\fi
\SIL@topauthortrue
\else
\typeout{Author won't fit in .9 of
\the\SIL@maxbookwidth}%
\fi
% \end{macrocode}
% We now have enough data to make a shot at the
% dimensions. Pick a random book height and set the height
% available for the title (set sideways) to 90\% of
% that, so that it fits comfortably. Then if the author
% was earlier assigned to the top of the spine, reduce
% this height available for the title by 1.2 times the
% height occupied by the author (again, to leave a little
% space). In this case, the width has already been set;
% otherwise, generate a random width now.\par
% \begin{macrocode}
\typeout{Limits: width=\the\SIL@minbookwidth
–\the\SIL@maxbookwidth;
height=\the\SIL@minbookheight
–\the\SIL@maxbookheight}%
\setrandim{\SIL@bookheight}%
{\SIL@minbookheight}%
{\SIL@maxbookheight}%
\typeout{Height generated as
\the\SIL@bookheight}%
\setlength{\SIL@heightfortitle}%
{.9\SIL@bookheight}%
\typeout{Height available for title (90\%):
\the\SIL@heightfortitle}%
\ifSIL@topauthor
\typeout{Width set because author fits:
\the\SIL@bookwidth}%
\addtolength{\SIL@heightfortitle}%
{-1.2\SIL@authorheight}%
\typeout{Height available for title reset to
\the\SIL@heightfortitle}%
\else
\setrandim{\SIL@bookwidth}%
{\SIL@minbookwidth}%
{\SIL@maxbookwidth}%
\typeout{Width generated as
\the\SIL@bookwidth}%
\fi
% \end{macrocode}
% Finally, set a {\ttfamily{}\textbackslash{}vbox} to the
% defined width \emph{less} the space
% occupied by the {\ttfamily{}\textbackslash{}fcolorbox} border and
% rule; then set the {\ttfamily{}\textbackslash{}fcolorbox} with the
% chosen colors, with the author at the top if that's what
% was selected earlier, and the title below, either scaled
% using {\ttfamily{}\textbackslash{}scalebox} if it was a
% single-line title, or with the amended font size if it
% was a multiline title.\par
% For a setting with the author inline to the title,
% just do the scaling of the title.\par
% \begin{macrocode}
\leavevmode\vbox{\hsize\SIL@bookwidth
\advance\hsize by2\fboxsep
\advance\hsize by2\fboxrule
\fcolorbox{black}{\SIL@bgcol}{%
\ifSIL@topauthor
\typeout{Setting with top author}%
\vbox to\SIL@bookheight{\hsize\SIL@bookwidth
\typeout{Spine is a vbox to
\the\SIL@bookheight,
hsize=\the\SIL@bookwidth}%
\centering
\SILmfont\color{\SIL@fgcol}%
#1%
\par\vfill
\SIL@fittext{\color{\SIL@fgcol}\SILmfont
#2}{\SIL@heightfortitle}{\SIL@bookwidth}%
{\SIL@titlebox}%
\rotatebox{90}{\box\SIL@titlebox}%
}%
\else
\typeout{Setting author inline to title}%
\vbox to\SIL@bookheight{\hsize\SIL@bookwidth
\SIL@fittext{\color{\SIL@fgcol}\SILmfont
#1\quad
---\quad#2}{\SIL@bookheight}{\SIL@bookwidth}%
{\SIL@titlebox}%
\rotatebox{90}{\box\SIL@titlebox}%
}%
\fi
}%
% \end{macrocode}
% At the bottom, add a colored bar to fake up the
% shelf the books stand on. The number is the number of
% the font that was selected, and is there for
% error-tracing purposes only.\par
% \begin{macrocode}
\\\fboxsep0pt\fboxrule0pt%
\colorbox{BurlyWood}{\hbox to\hsize{%
\hfil\vrule height3mm depth6mm width0pt
\normalfont\scriptsize\theSIL@fontsel\hfil}}%
}%
\penalty0
\else % font not found
\typeout{Did not find font for #1--#2}%
\fi}
% \end{macrocode}
% \end{CPK@macro}
%
% \begin{macrocode}
\raggedright
% \end{macrocode}
%
% \iffalse
%</class>
% \fi
% \nocite{*}
% \clearpage
% \raggedright
% \raggedright\printbibliography
% \Finale