1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
%%
%% This is file `novel-Images.sty', part of class `novel'.
%% Copyright 2017 Robert Allgeyer.
%%
%%
%% This file 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 2005/12/01 or later.
%%
%%
\ProvidesFile{novel-Images.sty}%
[2017/10/04 v1.42 LaTeX file (image placement)]
%%
%%
%% Be sure to read the separate documentation about how to prepare images.
%% In general: (1) png or jpg only. (2) Flattened, no transparency.
%% (3) 300dpi (grayscale) or 600dpi (black/white) are industry norms.
%% (4) Image file must contain its resolution. (5) Exact size, without scaling.
%% (6) No private metadata. (7) Be sure grayscale is 1-channel, not rgb gray.
%%
% \InlineImage[hoffset,voffset]{imagefile.png or jpg} and starred version.
%
% Use hoffset to displace the image horizontally. Positive is to the right.
% Use voffset to displace the image vertically. Positive is upward.
% Can use hoffset by itself, then voffset defaults to 0pt.
%
% The TOP of the image is placed at the baseline of text (unless offset).
% To place image so that its BOTTOM (rather than top) is at the text baseline,
% use voffset b. Can also use b+2em or b-3.4pt etc. without spaces.
% To place image so that its top is as text X height, voffset \heightof{X}.
%
% You can combine lengths, such as:
% voffset 0.2em+\heightof{X} or b-\heightof{Aring}+0.5em
% However, do not begin the string with + or - followed directly by \heightof.
%
% Unstarred command: Image occupies its natural width, so that following text
% (if on same line) is after the image.
% Starred command: Image occupies zero width, so that following text (if on
% the same line) overlays the image.
% In all cases, the image occupies zero height, so that following text lines
% will overlay the image, unless you insert some \null lines.
% In some case, having following text overlay the image is desirable. But talk
% with your print service about that. Not all like it.
% If the image rises above its line of text, it may overlay text on the
% preceding line, which obscures that text. Don't do it.
%
% Clever use of hoffset, with narrowed textblock, can place text beside image.
%
% \imagewidth and \imageheight may be used for offsets, or for any other
% purpose once the image is placed. These lengths retain their values
% until a subsequent image is placed, not including anything in header/footer.
%
\def\Aring{Å} % has typical maximum accented character height in Latin-1.
%
\newlength\imagewidth
\newlength\imageheight
\newlength\imagehoffset
\newlength\imagevoffset
\newlength\@imagewidth
\newlength\@imageheight
\newlength\@imagehoffset
\newlength\@imagevoffset
\gdef\imagestarred{false}
\gdef\imagefilename{unknown}
% Neutralize \includegraphics, so it is no longer a user command:
\let\@includegraphics\includegraphics\relax
\let\includegraphics\relax
\newcommand\includegraphics[2][]{
\ClassError{novel}{Cannot use \string\includegraphics\space on page \thepage}
{The `novel' class has its own commands for placing images. See docs.^^J%
You cannot use the \string\includegraphics\space command.}%
}
%
% \InlineImage can be used in body, header, footer.
% However, macros such as \imagefilename, \imagewidth, etc.
% are only set or re-set when the image in in the body.
% That prevents an intervening header/footer image from over-writing
% values set by the most recent body image.
% The unstarred command occupies the width of the image.
% The starred command occupies zero width.
%
\ExplSyntaxOn
\DeclareDocumentCommand \InlineImage { s O{0pt} m }{%
\newif\if@imgExtOK%
\IfEndWith{#3}{png}{\@imgExtOKtrue}{}%
\IfEndWith{#3}{PNG}{\@imgExtOKtrue}{}%
\IfEndWith{#3}{jpg}{\@imgExtOKtrue}{}%
\IfEndWith{#3}{JPG}{\@imgExtOKtrue}{}%
\IfEndWith{#3}{jpeg}{\@imgExtOKtrue}{}%
\IfEndWith{#3}{JPEG}{\@imgExtOKtrue}{}%
\if@imgExtOK\else%
\ClassError{novel}{^^JImage~`#3'~format~not~allowed}%
{^^JImage~`#3'~has~file~type~not~allowed~in~`novel'~class.^^J%
Must~have~file~extension~png,~jpg,~jpeg~(or~capitalized).^^J%
Others~such~as~pdf~bmp,~tiff,~eps,~pdf,~svg~are~not~allowed.^^J}%
\fi%
\StrDel{#2}{\space}[\@myila]%
\StrCut{\@myila}{,}{\@myilxa}{\@myilya}%
\ifthenelse{\equal{\@myilxa}{} \OR \equal{\@myilxa}{0}}{%
\def\@myilx{0pt}}{\def\@myilx{\@myilxa}%
}%
\ifthenelse{\equal{\@myilya}{} \OR \equal{\@myilya}{0}}{%
\def\@myily{0pt}}{\def\@myily{\@myilya}%
}%
\iftoggle{@inheadfoot}{}{\gdef\imagefilename{#3}}% for possible later use
\gdef\my@graphic{\@includegraphics[draft=false]{#3}}%
\setlength\@imagewidth{\widthof{\my@graphic}}%
\global\@imagewidth=\@imagewidth%
\iftoggle{@inheadfoot}{}{\setlength\imagewidth{\@imagewidth}}%
\setlength\@imageheight{\heightof{\my@graphic}}%
\global\@imageheight=\@imageheight%
\iftoggle{@inheadfoot}{}{%
\setlength\imageheight{\@imageheight}%
\global\imageheight=\imageheight%
\typeout{^^JClass~`novel'~Info:~An~image~was~placed~on~page~\thepage.^^J%
Review~layout~to~ensure~that~it~does~not~overflow~into~margins.^^J}%
}%
%
\setlength\@imagehoffset{\@myilx}%
\IfBeginWith{\@myily}{b}{%
\StrDel[1]{\@myily}{b}[\temp@adjVoffseta]%
\ifthenelse{\equal{\temp@adjVoffseta}{} \OR \equal{\temp@adjVoffseta}{0}}{%
\def\temp@adjVoffset{0pt}}{\def\temp@adjVoffset{\temp@adjVoffseta}%
}%
\setlength\@imagevoffset{\temp@adjVoffset}%
}{%
\setlength\@imagevoffset{-\@imageheight}%
\addtolength\@imagevoffset{\@myily}%
}%
%
\IfBooleanTF{#1}%
% starred:
{%
\iftoggle{@inheadfoot}{}{\gdef\imagestarred{true}}%
\makebox[0pt][l]{%
\hspace{\@imagehoffset}%
\stake\smash{\raisebox{\@imagevoffset}{\my@graphic}}%
}%
}%
% unstarred:
{%
\iftoggle{@inheadfoot}{}{\gdef\imagestarred{false}}%
\hspace{\@imagehoffset}%
\stake\smash{\raisebox{\@imagevoffset}{\my@graphic}}%
}% end IfBooleanTF{#1}
\iftoggle{@inheadfoot}{}{\setlength\imagehoffset{\@imagehoffset}}%
\iftoggle{@inheadfoot}{}{\setlength\imagevoffset{\@imagevoffset}}%
} % end DeclareDocumentCommand \InlineImage
\ExplSyntaxOff
%
%%
%% \BlockImage[alignment]{image}[text]
% Alignment may have up to 3 comma-separated values. Default is [c]
% First alignment: l, c, r (left, center, right).
% Second alignment: x-offset of image (not text). Default 0pt. May use 0.
% Third alignment: y-offset of image (not text). Default 0pt. May use 0.
% Offsets are positive right and up.
% The optional text, if used, must have its opening bracket immediately
% follow the image closing brace, without intervening space.
% Text may have line break or more than one paragraph, and may be styled.
% But any font family change must go outside this command, not within the text.
% The text will begin in the same block of vertical space as the image.
% If image is centered, the text will automatically be centered, so that
% it necessarily overlies the image.
% \forceindent or \backindent may be needed. Text may have several paragraphs.
% Subsequent text (after all that) will clear the image bottom, and also
% be at the baseline grid. Beware of using this command near bottom of page.
\ExplSyntaxOn
\DeclareDocumentCommand \BlockImage { O{c} m +O{} }{
\iftoggle{@inheadfoot}{%
\ClassError{novel}{Cannot~use~BlockImage~in~header~or~footer}%
{Header~footer~allow~InlineImage~but~not~BlockImage.}%
}{}%
% Allows empty or blank to be used, and still provide default values:
\ifthenelse{\equal{#1}{} \OR \equal{#1}{\space}}{%
\def\@myargs{c}}{\def\@myargs{#1}%
}
\StrDel{\@myargs}{\space}[\@myargsns] % needs {\space} not { }
\StrCut{\@myargsns}{,}{\@myalign}{\@mycoord}
\StrCut{\@mycoord}{,}{\@myxt}{\@myyt}
\ifthenelse{\equal{\@myxt}{}\OR\equal{\@myxt}{0}}{%
\def\@myx{0pt}}{\def\@myx{\@myxt}%
}
\ifthenelse{\equal{\@myyt}{}\OR\equal{\@myyt}{0}}{%
\def\@myy{0pt}}{\def\@myy{\@myyt}%
}
\newdimen\@sbsheight
\ifthenelse{\equal{\@myalign}{c}\OR\equal{\@myalign}{}}{%
{\centering\strut\InlineImage*[{\@myx-0.5\imagewidth},{\@myy}]{#2}\par}
\vspace*{-\nbs}
{\centering\strut #3\par}
\setbox0=\vbox{{\centering #3\par}}
}{}
\ifthenelse{\equal{\@myalign}{r}}{%
\noindent\InlineImage[{\textwidth-\imagewidth+\@myx},{\@myy}]{#2}\par%
\vspace{-\nbs}
\begin{adjustwidth}{0pt}{\imagewidth+\parindent}%
#3\par%
\end{adjustwidth}%
\setbox0=\vbox{%
\begin{adjustwidth}{0pt}{\imagewidth+\parindent}%
#3\par%
\end{adjustwidth}%
}%
}{}
\ifthenelse{\equal{\@myalign}{l}}{%
\noindent\InlineImage*[{\@myx},{\@myy}]{#2}\par%
\vspace{-\nbs}
\begin{adjustwidth}{\imagewidth+\parindent}{0pt}%
#3\par%
\end{adjustwidth}%
\setbox0=\vbox{%
\begin{adjustwidth}{\imagewidth+\parindent}{0pt}%
#3\par%
\end{adjustwidth}%
}%
}{}
% portion here, inspired by post from user Killian Foth,
% at stackoverflow.com, license CC-by-sa-3.0.
\@sbsheight=\ht0 \advance\@sbsheight by \dp0
\def\@sbsheightnum{\strip@pt\@sbsheight}
\FPdiv{\@roughlines}{\@sbsheightnum}{\nbsnum}
\FPadd{\@roughlines}{\@roughlines}{0.5} % round up, not down
\FPround{\@roughlines}{\@roughlines}{0}
\gdef\@imageheightnum{\strip@pt\@imageheight}%
\FPdiv{\@imagelines}{\@imageheightnum}{\nbsnum}%
\FPadd{\@imagelines}{\@imagelines}{0.5}% round up to integer, not down
\FPround{\@imagelines}{\@imagelines}{0}%
\FPclip{\@imagelines}{\@imagelines}%
\gdef\imagelineskip{\@imagelines}%
\FPclip{\@roughlines}{\@roughlines}
\FPadd{\@adjimagelines}{\imagelineskip}{1} % \imagelineskip from \InlineImage*
\FPsub{\@skipme}{\@adjimagelines}{\@roughlines}
\FPmax{\@skipme}{\@skipme}{0}
\vspace{\@skipme\nbs}
}
\ExplSyntaxOff
%%
% Returns 1 for monochrome, 8 for grayscale (or rgb). EXPERIMENTAL.
% Not documented. Not used as part of any other commands.
\gdef\imagecolordepth{%
\ifthenelse{\equal{\imagefilename}{unknown}}{unknown}{%
\directlua{%
img1=img.scan{filename="\imagefilename"}%
tex.print(tostring(img1.colordepth))%
}%
}%
}
%
%%
%% End of file `novel-Images.sty'.
|