strc-not.mkvi /size: 71 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=strc-not,
3
%D version=2008.10.20,
4
%D title=\CONTEXT\ Structure Macros,
5
%D subtitle=Note Handling,
6
%D author=Hans Hagen,
7
%D date=\currentdate,
8
%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9
%C
10
%C This module is part of the \CONTEXT\ macro||package and is
11
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12
%C details.
13 14
\writestatus
{
loading
}{
ConTeXt
Structure
Macros
/
Note
Handling
}
15 16
\registerctxluafile
{
strc
-
not
}{}
17 18
\unprotect
19 20
% todo: finish local rendering
21
% todo: more p_strc_notations_* (outside trial loop)
22
% todo: see if we can now use \insertpenalties (>0 == some left)
23 24
\ifdefined
\dotagsetnotesymbol
\else
\let
\dotagsetnotesymbol
\relax
\fi
25
\ifdefined
\dotagsetnotation
\else
\let
\dotagsetnotation
\relax
\fi
26 27
\unexpanded
\def
\unvboxed
{
\ifvmode
\unvbox
\else\box
\fi
}
% will change or used more often
28
\unexpanded
\def
\unvcopied
{
\ifvmode
\unvcopy\else\copy\fi
}
% will change or used more often
29 30
%D Notes have two handlers: notations and notes. Although notations can
31
%D be defined independently it makes not much sense. In principle we can
32
%D treat notes as lists but they are currently done as a variant on
33
%D enumerations. I will provide a list variant as well. One complication is
34
%D that for page related notes inserts are used and therefore notes are
35
%D typeset immediately and descriptions are better suited for that. For
36
%D instance endnotes can as well be typeset using lists.
37 38
% textcommand/textstyle/textcolor : set by note commandhandler and used for inline number
39 40
%D \macros
41
%D {setupnote,setupnotation}
42
%D
43
%D We can influence footnote typesetting with the setup
44
%D command:
45
%D
46
%D \showsetup{setupnotation}
47
%D \showsetup{setupnote}
48
%D
49
%D The definition command indicate that we can frame the footnote
50
%D area. The footnotes themselves are treated as descriptions.
51
%D
52
%D \showsetup{definenote}
53
%D
54
%D It's sort of a custom to precede footnotes by a horizontal
55
%D rule and although fancy rules like
56
%D
57
%D \starttyping
58
%D \hbox to 10em{\hskip-3em\dotfill}
59
%D \stoptyping
60
%D
61
%D Are quite ligitimate, we default to a simple one 20\% of the
62
%D text width.
63 64
% \c!headstyle=\noteparameter\c!style,
65
% \c!headcolor=\noteparameter\c!color,
66 67
\installcorenamespace
{
notation
}
68 69
\installcommandhandler
\??notation
{
notation
}
\??notation
70 71
\installcounterassociation
{
notation
}
72 73
\let
\setupnotations\setupnotation
74 75
\definesymbol
[
\v!note
:
\v!previouspage
][
\llap
{
\low
{
\symbol
[
\v!previouspage
]
}}
]
76
\definesymbol
[
\v!note
:
\v!nextpage
][
\llap
{
\low
{
\symbol
[
\v!nextpage
]
}}
]
77 78
\setupnotations
% check with old
79
[
\c!alternative
=
\v!note
,
80
%\c!headstyle=,
81
%\c!titlestyle=,
82
%\c!style=,
83
%\c!color=,
84
%\c!headcolor=,
85
%\c!titlecolor=,
86
\c!numbercommand
=
\high
,
87
%\c!symbolcommand=\lowllap, % experiment
88
%\c!indicator=\v!no, % was \v!yes in mkii for page notes
89
\c!width
=
\v!fit
,
90
\c!titledistance
=
.
5
em
,
91
\c!distance
=
.
5
em
,
92
%\c!hang=,
93
%\c!sample=,
94
%\c!align=,
95
%\c!headalign=,
96
\c!margin
=
\v!no
,
97
\c!before
=
,
98
\c!inbetween
=
,
99
\c!after
=
,
100
\c!indentnext
=
\v!yes
,
101
\c!indenting
=
\v!never
,
102
\c!titleleft
=(
,
103
\c!titleright
=)
,
104
%\c!closesymbol=,
105
\c!closecommand
=
\wordright
,
106
\c!display
=
\v!yes
,
107
%\c!command=,
108
\c!titlecommand
=
,
109
\c!expansion
=
\v!no
,
110
%\c!xmlsetup=,
111
%\s!catcodes=,
112
\c!way
=
\v!by\v!text
,
113
\c!prefix
=
\v!no
,
114
\c!prefixconnector
=
.
,
115
%\c!starter=,
116
%\c!stopper=,
117
\c!number
=
\v!yes
,
118
\c!text
=
,
119
\c!start
=
0
,
120
\c!state
=
\v!start
,
121
\c!levels
=
3
]
122 123
%D The code here is mostly the same as enumerations but we want to keep them
124
%D isolated and at some point we might differentiate.
125 126
% \installcorenamespace{noteclass}
127 128
\unexpanded
\def
\strc_define_commands_notation
#
tag
#
level
#
parent
%
129
{
\doifelsenothing
{
#
parent
}
130
{
\normalexpanded
{
\defineconstruction
[#
tag
][
\s!handler
=
\v!notation
,
\c!level
=#
level
]
}
%
131
\setevalue
{
\??notation
#
tag
:
\s!parent
}{
\??notation
}}
%
132
{
\normalexpanded
{
\defineconstruction
[#
tag
][#
parent
][
\s!handler
=
\v!notation
,
\c!level
=#
level
]
}
%
133
\setevalue
{
\??note
#
tag
:
\s!parent
}{
\??note
#
parent
}
% see later for \s!note
134
\setevalue
{
\??notation
#
tag
:
\s!parent
}{
\??notation
#
parent
}}
%
135
\setuevalue
{
\e!next
#
tag
}{
\strc_notations_next
{
#
tag
}{
\number
#
level
}}
% obsolete
136
\setuevalue
{
\c!reset
#
tag
}{
\strc_notations_reset
{
#
tag
}{
\number
#
level
}}
% obsolete
137
%setuevalue{\c!set #tag}{\strc_notations_set {#tag}{\number#level}}% obsolete
138
\setuevalue
{
#
tag
}{
\strc_notations_command
{
#
tag
}}
%
139
\setuevalue
{
\e!start
#
tag
}{
\strc_notations_start
{
#
tag
}{
#
tag
}}
% okay?
140
\setuevalue
{
\e!stop
#
tag
}{
\strc_notations_stop
}}
141 142
\appendtoks
143
\ifx
\currentnotationparent
\empty
144
% clone => parent | subclone => clone | subsubclone => subclone
145
\let
\currentnotationsub
\empty
146
\strc_define_commands_notation
147
{
\currentnotationsub
\currentnotation
}
%
148
\plusone
149
\empty
150
\edef
\p_levels
{
\notationparameter
\c!levels
}
%
151
\dostepwiserecurse
\plustwo
\p_levels
\plusone
152
{
\strc_define_commands_notation
153
{
\v!sub
\currentnotationsub
\currentnotation
}
%
154
\recurselevel
155
{
\currentnotationsub
\currentnotation
}
%
156
\edef
\currentnotationsub
{
\v!sub
\currentnotationsub
}}
%
157
\definelist
[
\currentnotation
]
% goodie
158
\else
159
% clone => parent | subclone => subparent | subsubclone => subsubparent
160
\let
\currentnotationsub
\empty
161
\edef
\p_levels
{
\notationparameter
\c!levels
}
%
162
\dorecurse
\p_levels
163
{
\strc_define_commands_notation
164
{
\currentnotationsub
\currentnotation
}
%
165
\recurselevel
166
{
\currentnotationsub
\currentnotationparent
}
%
167
\edef
\currentnotationsub
{
\v!sub
\currentnotationsub
}}
%
168
\definelist
[
\currentnotation
][
\currentnotationparent
]
% goodie
169
\fi
170
\edef
\p_counter
{
\notationparameter
\s!counter
}
% can inherit from parent
171
\ifx
\p_counter
\empty
%
172
\let
\p_counter
\currentnotation
173
\fi
174
\doifelsecounter
\p_counter
\donothing
{
\strc_notes_define_counter
\p_counter
}
%
175
\letnotationparameter
\s!counter
\p_counter
176
%\strc_notes_setup_counter\currentnotation
177
\to
\everydefinenotation
178 179
\let
\p_strc_constructions_title
\empty
180
\let
\p_strc_constructions_number
\empty
181 182
\unexpanded\setvalue
{
\??constructioninitializer\v!notation
}
%
183
{
\let
\currentnotation
\currentconstruction
184
\let
\constructionparameter
\notationparameter
185
\let
\constructionnamespace
\??notation
186
\let
\detokenizedconstructionparameter
\detokenizednotationparameter
187
\let
\letconstructionparameter
\letnotationparameter
188
\let
\useconstructionstyleandcolor
\usenotationstyleandcolor
189
\let
\setupcurrentconstruction
\setupcurrentnotation
190
\edef
\p_strc_constructions_number
{
\constructionparameter
\c!number
}
%
191
\ifx
\p_strc_constructions_number
\v!yes
192
\settrue
\c_strc_constructions_number_state
193
\iftrialtypesetting
194
\strc_counters_save
\currentconstructionnumber
195
\fi
196
% \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
197
\else
198
\setfalse
\c_strc_constructions_number_state
199
\fi
200
\edef
\p_strc_constructions_title
{
\constructionparameter
\c!title
}
%
201
\ifx
\p_strc_constructions_title
\v!yes
202
\settrue
\c_strc_constructions_title_state
203
\else
204
\setfalse
\c_strc_constructions_title_state
205
\fi
}
206 207
\unexpanded\setvalue
{
\??constructionfinalizer\v!notation
}
%
208
{
\ifconditional
\c_strc_constructions_number_state
209
\iftrialtypesetting
210
\strc_counters_restore
\currentconstructionnumber
211
\fi
212
\fi
}
213 214
%D Notations (we simply needed a word that relates to notes and is
215
%D and sounds like description and enumeration) are a special case
216
%D in the sense that they are stored, rendered elsewhere and referered
217
%D to from where they are specified. For that reason they have a different
218
%D set op main commands.
219 220
% \notation[ref]{title}
221
% \notation[reference=,title=]
222
% \startnotation[ref] title \stopnotation
223 224
\unexpanded
\def
\strc_notations_next
{
\strc_constructions_next_indeed
\namednotationparameter
}
% #1#2
225
\unexpanded
\def
\strc_notations_reset
{
\strc_constructions_reset_indeed
\namednotationparameter
}
% #1#2
226
%unexpanded\def\strc_notations_set {\strc_constructions_set_indeed \namednotationparameter} % #1#2
227 228
\newconditional
\c_strc_notations_anchored_next
229 230
\def
\strc_notations_finalize
231
{
\ifconditional
\c_strc_notations_anchored_next
232
\expandafter
\strc_notations_finalize_next
233
\else
234
\expandafter
\strc_notations_finalize_previous
235
\fi
}
236 237
\def
\strc_notations_finalize_previous
238
{
\normalexpanded
{
\endgroup
\noteparameter
\c!next
}}
239 240
\def
\strc_notations_finalize_next
241
{
\endgroup\ignorespaces
}
242 243
\unexpanded
\def
\strc_notations_command
#
tag
%
244
{
\begingroup
245
\edef
\currentnote
{
#
tag
}
%
246
\strc_constructions_initialize
{
#
tag
}
%
247
\strc_notes_synchronize
248
\edef
\p_next
{
\noteparameter
\c!anchor
}
%
249
\ifx
\p_next
\v!next
% for now only two states
250
\settrue
\c_strc_notations_anchored_next
251
\else
252
\setfalse
\c_strc_notations_anchored_next
253
\fi
254
\ifnotesenabled
255
\strc_counters_increment_sub
\currentconstructionnumber
\currentconstructionlevel
256
\fi
257
\doifelsenextoptionalcs
\strc_notations_command_yes
\strc_notations_command_nop
}
258 259
\unexpanded
\def
\strc_notations_command_nop
#
title
%
260
{
\strc_constructions_register
[][
\c!label
=
{
\descriptionparameter
\c!text
}
,
\c!reference
=
,
\c!title
=
{
#
title
}
,
\c!bookmark
=
,
\c!list
=]
%
261
\csname
\??constructionnotehandler
\currentconstructionhandler
\endcsname
262
\strc_constructions_finalize
263
\strc_notations_finalize
}
264 265
\unexpanded
\def
\strc_notations_command_yes
[#
optional
]
%
266
{
\doifelseassignment
{
#
optional
}
\strc_notations_command_assignment
\strc_notations_command_argument
[#
optional
]
}
267 268
\unexpanded
\def
\strc_notations_command_assignment
[#
settings
]
%
269
{
\strc_constructions_register
[][
\c!label
=
{
\descriptionparameter
\c!text
}
,
\c!reference
=
,
\c!title
=
,
\c!bookmark
=
,
\c!list
=
,
#
settings
]
%
270
\csname
\??constructionnotehandler
\currentconstructionhandler
\endcsname
271
\strc_constructions_finalize
272
\strc_notations_finalize
}
273 274
\unexpanded
\def
\strc_notations_command_argument
[#
reference
]#
title
%
275
{
\strc_constructions_register
[][
\c!label
=
{
\descriptionparameter
\c!text
}
,
\c!reference
=
{
#
reference
}
,
\c!title
=
{
#
title
}
,
\c!bookmark
=
,
\c!list
=]
%
276
\csname
\??constructionnotehandler
\currentconstructionhandler
\endcsname
277
\strc_constructions_finalize
278
\strc_notations_finalize
}
279 280
\unexpanded
\def
\strc_notations_start
#
tag
#
stoptag
%
281
{
\begingroup
282
\edef
\currentnote
{
#
tag
}
%
283
\strc_constructions_initialize
{
#
tag
}
%
284
\strc_notes_synchronize
285
\ifnotesenabled
286
\strc_counters_increment_sub
\currentconstructionnumber
\currentconstructionlevel
287
\fi
288
\normalexpanded
% not that efficient but also not that frequently used (\normaldef for parser)
289
{
\def\noexpand
\strc_pickup_yes
[#
one
]#
two
\csname
\e!stop
#
stoptag
\endcsname
{
\strc_notations_command_yes
[#
one
]
{
#
two
}}
%
290
\def\noexpand
\strc_pickup_nop
#
one
\csname
\e!stop
#
stoptag
\endcsname
{
\strc_notations_command_nop
{
#
one
}}}
%
291
\doifelsenextoptionalcs
\strc_pickup_yes
\strc_pickup_nop
}
292 293
\unexpanded
\def
\strc_notations_start_yes
[#
reference
]#
title
%
294
{
\strc_constructions_register
[][
\c!label
=
{
\descriptionparameter
\c!text
}
,
\c!reference
=
{
#
reference
}
,
\c!title
=
{
#
title
}
,
\c!bookmark
=
,
\c!list
=]
%
295
\csname
\??constructionnotehandler
\currentconstructionhandler
\endcsname
296
\strc_constructions_finalize
297
\strc_notations_finalize
}
298 299
\unexpanded
\def
\strc_notations_start_nop
#
title
%
300
{
\strc_constructions_register
[][
\c!label
=
{
\descriptionparameter
\c!text
}
,
\c!reference
=
,
\c!title
=
{
#
title
}
,
\c!bookmark
=
,
\c!list
=]
%
301
\csname
\??constructionnotehandler
\currentconstructionhandler
\endcsname
302
\strc_constructions_finalize
303
\strc_notations_finalize
}
304 305
\unexpanded
\def
\strc_notations_stop
306
{}
307 308
%D A complication is that we need to set up rather specific properties
309
%D of e.g. footnotes. It is for this reason that we introduce an extra
310
%D level of indirectness. This way notations don't bark on undefined
311
%D macros when used in combination.
312 313
\unexpanded\setvalue
{
\??constructionnotehandler\v!notation
}
%
314
{
\csname
\??constructionnotehandler
\currentconstructionhandler
:
\constructionparameter
\c!type
\endcsname
}
315 316
\unexpanded\setvalue
{
\??constructionnotehandler\v!notation
:
}
% empty case
317
{
[
\currentconstructionhandler
:
\currentconstruction
]
}
318 319
%D Here is a simple renderer for notes
320 321
\defineconstructionalternative
322
[
\v!note
]
323
[
\c!renderingsetup
=
\??constructionrenderings
:
\v!note
]
324 325
\startsetups
[
\??constructionrenderings
:
\v!note
]
326
\noindent
327
\leftboundary
% experiment, to be done in more places
328
\llap
{
\box
\constructionheadbox
\hskip
\constructionparameter
\c!distance
}
%
329
\useconstructionstyleandcolor
\c!style\c!color
330
\ignorespaces
331
\stopsetups
332 333
%D We now implement the note definer.
334 335
\installcorenamespace
{
note
}
336 337
\installframedcommandhandler
\??note
{
note
}
\??note
338 339
\let
\setupnotes\setupnote
340 341
% These only concern the inline symbol/number and wrapping of the
342
% whole list.
343 344
\setupnotes
% not all make sense here
345
[
\c!location
=
\v!page
,
346
%\c!conversion=,
347
\c!rule
=
\v!on
,
348
\c!before
=
\blank
,
349
\c!bodyfont
=
\v!small
,
350
\c!anchor
=
,
% can also be v!next
351
%\c!style=,
352
%\c!color=,
353
%\c!after=,
354
%\c!rulecolor=,
355
%\c!rulecommand=,
356
\c!rulethickness
=
\linewidth
,
357
\c!frame
=
\v!off
,
358
\c!distance
=
.
1
2
5
em
,
% in the text between symbols
359
% \c!textseparator={,}, % optional separator
360
\c!columndistance
=
1
em
,
361
% \c!margindistance=.5em,
362
\c!align
=
,
% also use instead of \c!tolerance
363
\c!split
=
\v!tolerant
,
364
\c!width
=
\makeupwidth
,
% \ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi
365
\c!height
=
\textheight
,
366
\c!command
=
,
% \noteparameter\c!numbercommand, % (command in enumeration) too messy, called twice
367
\c!separator
=
,
%
368
\c!textcommand
=
\high
,
369
\c!textstyle
=
\tx
,
370
%\c!textcolor=,
371
\c!interaction
=
\v!yes
,
372
%\c!factor=,
373
%\c!scope=, % \v!text \v!page
374
\c!prefixconnector
=
.
,
375
%\c!next=\autoinsertnextspace,
376
\c!prefix
=
\v!no
,
377
%\c!continue=\v!no,
378
\c!paragraph
=
\v!no
,
379
\c!inbetween
=
\hskip
\emwidth
,
380
\c!symbol
=
\mathematics
{
*
}
,
381
\c!n
=
1
]
382 383
\setupnotes
384
[
\c!expansion
=
\v!no
,
385
\c!xmlsetup
=
,
386
\s!catcodes
=]
387 388
%D Insertions are part of notes.
389 390
% \installcorenamespace{noteinsertion}
391 392
\def
\currentnoteinsertion
{
\noteparameter
\s!insert
}
393
\def
\currentnoteinsertionnumber
{
\namedinsertionnumber
{
\noteparameter
\s!insert
}}
394 395
\appendtoks
396
\ifx
\currentnoteparent
\empty
397
\doifelseinsertion
\currentnote
398
\donothing
399
{
\defineinsertion
[
\currentnote
]
% could be an option
400
\normalexpanded
{
\t_strc_notes
{
\the
\t_strc_notes
\noexpand
\strc_notes_process_list
{
\currentnote
}}}}
%
401
\letnoteparameter
\s!insert
\currentnote
402
\definenotation
[
\currentnote
][
\c!type
=
\v!note
]
%
403
\else
404
\setexpandednoteparameter
\s!insert
{
\namednoteparameter
\currentnoteparent
\s!insert
}
%
405
\definenotation
[
\currentnote
][
\currentnoteparent
][
\c!type
=
\v!note
]
%
406
\fi
407
\clf_definenote
408
{
\currentnote
}
%
409
{
insert
}
%
410
\currentnoteinsertionnumber
411
\relax
412
\to
\everydefinenote
413 414
% maybe we will share this at some point:
415 416
\def
\strc_notes_define_counter
#
tag
% todo: move inline
417
{
\definecounter
[#
tag
]
%
418
\registerenumerationcounter
{
#
tag
}}
419 420
\appendtoks
421
\synchronizenotationcounters
422
\to
\everysetupnotation
423 424
\appendtoks
425
\synchronizenotationcounters
426
\to
\everydefinenotation
427 428
% so far
429 430
%expandafter\let\csname\??constructionstarthandler \v!notation\expandafter\endcsname\csname\??constructionstarthandler \v!enumeration\endcsname
431
\expandafter\let\csname
\??constructionstarthandler
\v!notation
\expandafter\endcsname\csname
\??constructionstarthandler
\v!construction
\endcsname
% no par mess
432
\expandafter\let\csname
\??constructionstophandler
\v!notation
\expandafter\endcsname\csname
\??constructionstophandler
\v!enumeration
\endcsname
433
\expandafter\let\csname
\??constructioncommandhandler\v!notation
\expandafter\endcsname\csname
\??constructioncommandhandler\v!enumeration
\endcsname
434
\expandafter\let\csname
\??constructiontexthandler
\v!notation
\expandafter\endcsname\csname
\??constructiontexthandler
\v!enumeration
\endcsname
435 436
\unexpanded\setvalue
{
\??constructionmainhandler\v!notation
}
#
following
%
437
{
\iftrialtypesetting
\else
438
\begingroup
439
\currentconstructionsynchronize
440
\c_attr_destination
\currentconstructionattribute
\relax
% todo, whole text
441
\signalcharacter
442
\endgroup
443
\fi
#
following
}
444 445
\unexpanded\setvalue
{
\??constructionnotehandler\v!notation
:
\v!note
}
% in the running text
446
{
\ifnotesenabled
447
% do be done elsewhere
448
%
449
%let\currentnote\currentconstructionmain
450
\let
\currentnote
\currentconstruction
% else wrong inheritance
451
%
452
\iftrialtypesetting
453
\strc_notes_inject_dummy
454
\else
455
\begingroup
456
\edef
\currentnotenumber
{
\clf_storenote
{
\currentnote
}
\currentconstructionlistentry
}
%
457
\settrue
\processingnote
458
\ifconditional
\c_strc_notes_skip
459
\glet
\lastnotesymbol
\strc_notes_inject_symbol_nop
460
\else
461
\iftypesettinglines
% otherwise problems with \type <crlf> {xxx}
462
\ignorelines
% makes footnotes work in \startlines ... \stoplines
463
\fi
464
\ifconditional
\c_strc_notes_symbol
465
\strc_notes_inject_symbol_yes
466
\else
467
\unskip\unskip
468
\glet
\lastnotesymbol
\strc_notes_inject_symbol_yes
469
\fi
470
\fi
471
\ifconditional
\postponingnotes
% todo: per note class
472
\global
\settrue
\postponednote
473
\else
\ifconditional
\inlocalnotes
% todo: per note class
474
\global
\settrue
\postponednote
475
\else
\ifconditional
\c_strc_notes_delayed
476
% probably end notes
477
\else
478
\handlenoteinsert
\currentnote
\currentnotenumber
% either an insert or just delayed
479
\fi\fi\fi
480
\endgroup
481
\fi
482
\fi
483
\ifconditional
\c_strc_notes_skip
484
\global
\setfalse
\c_strc_notes_skip
485
\else
486
\kern
\notesignal
\relax
% \relax is needed to honor spaces
487
\fi
}
488 489
%D Interaction in notes is somewhat complex due to the way notes get
490
%D flushed. In principle it is more or less the same as lists but where
491
%D in lists we pack whole entries, in notes this doesn't happen. Okay,
492
%D in retrospect we could have made descriptions lists but that will be
493
%D a backward compatibility mess. At some point a completely new mechanism
494
%D might show up, but not now. Also, as notes are inserts there is some
495
%D extra mess to be kept in mind and it's easier to maintain two mechanisms
496
%D than to combine too much.
497
%D
498
%D Interaction is also complicated because we want to provide several variants.
499
%D For simple reference there is no need for anything special, as page references
500
%D will do and we store them in the list anyway. But if we want a destination with
501
%D dimensions we will use an additional destination because we can have only
502
%D one with the same name and we always have the number as one.
503 504
% interaction:
505
%
506
% all : text and number
507
% number|yes: only number
508
% text : only text
509
%
510
% \dogetsimple : injects
511 512
\installcorenamespace
{
noteinteractioninline
}
513
\installcorenamespace
{
noteinteractiondisplay
}
514 515
\newconstant
\a_strc_notes_symbol_reference
516
\newconstant
\a_strc_notes_number_reference
517
\newconstant
\a_strc_notes_text_reference
518
\newconstant
\a_strc_notes_text_destination
519 520
\let
\strc_notes_get_reference_attribute_symbol
\empty
521
\let
\strc_notes_get_destination_attribute_symbol
\empty
522 523
\def
\strc_notes_interaction_check_inline
524
{
\edef
\p_interaction
{
\noteparameter
\c!interaction
}
%
525
\csname
\??noteinteractioninline
526
\ifcsname
\??noteinteractioninline
\p_interaction
\endcsname
\p_interaction
\else
\v!no
\fi
527
\endcsname
}
528 529
\def
\strc_notes_interaction_check_display
530
{
\edef
\p_interaction
{
\noteparameter
\c!interaction
}
%
531
\csname
\??noteinteractiondisplay
532
\ifcsname
\??noteinteractiondisplay
\p_interaction
\endcsname
\p_interaction
\else
\v!no
\fi
533
\endcsname
}
534 535
\def
\currentnotenumber
{
0
}
536 537
\let
\strc_notes_get_reference_attribute_symbol
\empty
538
\let
\strc_notes_get_destination_attribute_symbol
\empty
539 540
\let
\strc_notes_set_reference_attribute_number
\donothing
541
\let
\strc_notes_set_reference_attribute_text
\donothing
542
\let
\strc_notes_set_destination_attribute_text
\donothing
543 544
% inline
545 546
\def
\strc_references_prepare_inline_references_nop
547
{
\let
\strc_notes_get_reference_attribute_symbol
\empty
548
\let
\strc_notes_get_destination_attribute_symbol
\empty
549
\let
\strc_notes_set_style_color_inline
\strc_notes_set_style_color_inline_nop
}
550 551
% \def\strc_references_prepare_inline_references_yes
552
% {\strc_references_set_simple_reference{symb:\currentnote:\currentnotenumber}% destination
553
% \strc_references_get_simple_reference{internal(\clf_noteinternal{\currentnote}\currentnotenumber)}% reference
554
% \edef\strc_notes_get_destination_attribute_symbol{attr\destinationattribute\currentdestinationattribute}%
555
% \edef\strc_notes_get_reference_attribute_symbol{attr\referenceattribute\currentreferenceattribute}%
556
% \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_yes}
557 558
\def
\strc_references_prepare_inline_references_yes
559
{
\edef
\currentnoteinternal
{
\clf_noteinternal
{
\currentnote
}
\currentnotenumber
}
%
560
\strc_references_set_simple_reference
{
*
\currentnoteinternal
}
% destination
561
\strc_references_get_simple_reference
{
internal
(
\currentnoteinternal
)
}
% reference
562
\edef
\strc_notes_get_destination_attribute_symbol
{
attr
\destinationattribute
\currentdestinationattribute
}
%
563
\edef
\strc_notes_get_reference_attribute_symbol
{
attr
\referenceattribute
\currentreferenceattribute
}
%
564
\let
\strc_notes_set_style_color_inline
\strc_notes_set_style_color_inline_yes
}
565 566
\letvalue
{
\??noteinteractioninline\v!no
}
\strc_references_prepare_inline_references_nop
567
\letvalue
{
\??noteinteractioninline\v!all
}
\strc_references_prepare_inline_references_yes
568
\letvalue
{
\??noteinteractioninline\v!number
}
\strc_references_prepare_inline_references_yes
569
\letvalue
{
\??noteinteractioninline\v!text
}
\strc_references_prepare_inline_references_yes
570
\letvalue
{
\??noteinteractioninline\v!yes
}
\strc_references_prepare_inline_references_yes
571 572
% display (for 'all' we need unique text and number attributes so we resolve twice
573
% as we otherwise don't get the number one which is lapped in the margin so we need
574
% to explicitly visit it)
575 576
\def
\strc_references_prepare_display_references_nop
577
{
\let
\strc_notes_set_reference_attribute_number
\donothing
578
\let
\strc_notes_set_reference_attribute_text
\donothing
579
\let
\strc_notes_set_destination_attribute_text
\donothing
580
\let
\strc_notes_set_style_color_display
\strc_notes_set_style_color_display_nop
}
581 582
% \def\strc_references_prepare_display_references_yes_number
583
% {\let\strc_notes_set_reference_attribute_text\donothing
584
% \strc_references_get_simple_reference{symb:\currentnote:\currentnotenumber}% reference
585
% \edef\strc_notes_set_reference_attribute_number{\c_attr_reference\currentreferenceattribute}%
586
% \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes}
587 588
% \def\strc_references_prepare_display_references_yes_text
589
% {\strc_references_get_simple_reference{symb:\currentnote:\currentnotenumber}% reference
590
% \edef\strc_notes_set_reference_attribute_text{\c_attr_reference\currentreferenceattribute}%
591
% \let\strc_notes_set_reference_attribute_number\donothing
592
% \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes}
593 594
% \def\strc_references_prepare_display_references_yes_all
595
% {\strc_references_get_simple_reference{symb:\currentnote:\currentnotenumber}% reference
596
% \edef\strc_notes_set_reference_attribute_text{\c_attr_reference\currentreferenceattribute}%
597
% \strc_references_get_simple_reference{symb:\currentnote:\currentnotenumber}% reference
598
% \edef\strc_notes_set_reference_attribute_number{\c_attr_reference\currentreferenceattribute}%
599
% \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes}
600 601
\def
\strc_references_prepare_display_references_yes_number
602
{
\edef
\currentnoteinternal
{
\clf_noteinternal
{
\currentnote
}
\currentnotenumber
}
%
603
\ifcase
\currentnoteinternal
\relax
604
\strc_references_prepare_display_references_nop
605
\else
606
\let
\strc_notes_set_reference_attribute_text
\donothing
607
\strc_references_get_simple_reference
{
*
\currentnoteinternal
}
% reference
608
\edef
\strc_notes_set_reference_attribute_number
{
\c_attr_reference
\currentreferenceattribute
}
%
609
\let
\strc_notes_set_style_color_display
\strc_notes_set_style_color_display_yes
610
\fi
}
611 612
\def
\strc_references_prepare_display_references_yes_text
613
{
\edef
\currentnoteinternal
{
\clf_noteinternal
{
\currentnote
}
\currentnotenumber
}
%
614
\ifcase
\currentnoteinternal
\relax
615
\strc_references_prepare_display_references_nop
616
\else
617
\strc_references_get_simple_reference
{
*
\currentnoteinternal
}
% reference
618
\edef
\strc_notes_set_reference_attribute_text
{
\c_attr_reference
\currentreferenceattribute
}
%
619
\let
\strc_notes_set_reference_attribute_number
\donothing
620
\let
\strc_notes_set_style_color_display
\strc_notes_set_style_color_display_yes
621
\fi
}
622 623
\def
\strc_references_prepare_display_references_yes_all
624
{
\edef
\currentnoteinternal
{
\clf_noteinternal
{
\currentnote
}
\currentnotenumber
}
%
625
\ifcase
\currentnoteinternal
\relax
626
\strc_references_prepare_display_references_nop
627
\else
628
\strc_references_get_simple_reference
{
*
\currentnoteinternal
}
% reference
629
\edef
\strc_notes_set_reference_attribute_text
{
\c_attr_reference
\currentreferenceattribute
}
%
630
\strc_references_get_simple_reference
{
*
\currentnoteinternal
}
% reference
631
\edef
\strc_notes_set_reference_attribute_number
{
\c_attr_reference
\currentreferenceattribute
}
%
632
\let
\strc_notes_set_style_color_display
\strc_notes_set_style_color_display_yes
633
\fi
}
634 635
\letvalue
{
\??noteinteractiondisplay\v!no
}
\strc_references_prepare_display_references_nop
636
\letvalue
{
\??noteinteractiondisplay\v!all
}
\strc_references_prepare_display_references_yes_all
637
\letvalue
{
\??noteinteractiondisplay\v!number
}
\strc_references_prepare_display_references_yes_number
638
\letvalue
{
\??noteinteractiondisplay\v!text
}
\strc_references_prepare_display_references_yes_text
639
\letvalue
{
\??noteinteractiondisplay\v!yes
}
\strc_references_prepare_display_references_yes_number
640 641
\let
\strc_notes_set_style_color_inline_nop
\usenotestyleandcolor
642
\let
\strc_notes_set_style_color_display_nop
\usenotationstyleandcolor
643 644
\unexpanded
\def
\strc_notes_set_style_color_inline_yes
#
style
#
color
%
645
{
\usenotestyleandcolor
#
style
#
color
%
646
\iflocation
\strc_notes_set_style_color_special
\fi
}
647 648
\unexpanded
\def
\strc_notes_set_style_color_display_yes
#
style
#
color
%
649
{
\usenotationstyleandcolor
#
style
#
color
%
650
\iflocation
\strc_notes_set_style_color_special
\fi
}
651 652
\def
\strc_notes_set_style_color_special
653
{
\iftrialtypesetting
654
% keep
655
\else\ifx
\currentcolorparameter
\empty
656
\scratchcounter
\clf_notedeltapage
{
\currentnote
}
\currentnotenumber
\relax
% todo calculate once
657
\setlocationcolorspecified
\scratchcounter
658
\fi\fi
}
659 660
\setvalue
{
\??constructiontexthandler\v!notation
}
%
661
{
\begingroup
662
% we need to retrigger the reference as otherwise it gets lost because we don't do nested
663
% references with the same id ... maybe some day if we can figure out a nice heuristic ...
664
% the problem is that normally it's no issue but here we lap into the margin, so maybe that's
665
% a criterium
666
% \strc_notes_interaction_check_display
667
\strc_notes_set_reference_attribute_number
668
\dotagsetnotation
669
\strc_notes_set_style_color_display
\c!headstyle\c!headcolor
670
\strc_enumerations_text
671
\endgroup
}
672 673
% in mkii the pointer only showed up in pagewise notes
674 675
\unexpanded
\def
\strc_notes_inject_pointer
% todo calculate once
676
{
\ifcase
\clf_notedeltapage
{
\currentnote
}
\currentnotenumber
\relax\relax
677
% unknown
678
\or
679
% same page
680
\or
681
\noteparameter
\c!symbolcommand
{
\symbol
[
\v!note
:
\v!nextpage
]
}
%
682
\or
683
\noteparameter
\c!symbolcommand
{
\symbol
[
\v!note
:
\v!previouspage
]
}
%
684
\fi
}
685 686
\unexpanded
\def
\strc_notes_inject_symbol_yes
687
{
\strc_notes_inject_symbol_indeed
\conditionaltrue
}
688 689
\unexpanded
\def
\strc_notes_inject_symbol_nop
690
{
\strc_notes_inject_symbol_indeed
\conditionalfalse
}
691 692
\definemargindata
693
[
strc
_
notes
_
destination
_
margin
]
694
[
\v!left
]
695
[
\c!margin
=
\zeropoint
,
696
\c!width
=
\zeropoint
,
697
\c!style
=
,
698
\c!color
=]
699 700
% \unexpanded\def\strc_notes_destination_hack
701
% {\ifx\strc_notes_get_destination_attribute_symbol\empty\else
702
% \strc_notes_destination_hack_indeed
703
% \fi}
704
%
705
% \unexpanded\def\strc_notes_destination_hack_indeed % can be a helper
706
% {\strc_notes_destination_margin
707
% {\setbox\scratchbox\hpack \strc_notes_get_destination_attribute_symbol{}%
708
% \wd\scratchbox\makeupwidth
709
% \ht\scratchbox\strutht
710
% \dp\scratchbox\strutdp
711
% \hpack to \zeropoint{\box\scratchbox\hss}}}
712 713
\unexpanded
\def
\strc_notes_inject_symbol_indeed
#
synchronize
%
714
{
\ifconditional
\c_strc_notations_anchored_next
\else
715
\removeunwantedspaces
716
\doifelseitalic
\/
\donothing
% Charles IV \footnote{the fourth}
717
\fi
718
\ifdim
\lastkern
=
\notesignal
719
% \kern\noteparameter\c!distance % yes or no note font? or main text
720
\strc_notes_inject_separator
721
\fi
722
\nobreak
723
\begingroup
724
\strc_notes_interaction_check_inline
725
\strc_notes_set_style_color_inline
\c!textstyle\c!textcolor
726
\hbox
\strc_notes_get_reference_attribute_symbol
\strc_notes_get_destination_attribute_symbol
\bgroup
727
% \hbox \strc_notes_get_reference_attribute_symbol \bgroup \strc_notes_destination_hack
728
\strc_references_flush_destination_nodes
% a bit late but ok
729
\dostarttagged
\t!descriptionsymbol
\currentnote
730
\dotagsetnotesymbol
731
\noteparameter
\c!textcommand
{
\clf_noteprefixednumber
{
\currentnote
}
\currentnotenumber
\relax
}
%
732
% the next one can cycle so we need to make sure it has no advance width
733
\doif
{
\noteparameter
\c!indicator
}
\v!yes
\strc_notes_inject_pointer
734
\dostoptagged
735
\egroup
736
\endgroup
737
\glet
\lastnotesymbol
\relax
}
738 739
\unexpanded
\def
\strc_notes_inject_dummy
% temp hack
740
{
\removeunwantedspaces
741
\doifelseitalic
\/
\donothing
% Charles IV \footnote{the fourth}
742
\ifdim
\lastkern
=
\notesignal
743
% \kern\noteparameter\c!distance % yes or no note font? or main text
744
\strc_notes_inject_separator
745
\fi
746
\nobreak
747
\hpack
to
.
5
\emwidth
{}
%
748
\glet
\lastnotesymbol
\relax
}
749 750
\unexpanded
\def
\strc_notes_inject_separator
% patch by WS due to request on list
751
{
\edef
\p_textseparator
{
\noteparameter
\c!textseparator
}
%
752
\ifx
\p_textseparator
\empty
753
\kern
\noteparameter
\c!distance
754
\else
755
% skip or kern
756
\nobreak
757
\hbox
\bgroup
758
\strc_notes_interaction_check_inline
759
\strc_notes_set_style_color_inline
\c!textstyle\c!textcolor
760
\noteparameter
\c!textcommand
{
\p_textseparator
}
%
761
\kern
\noteparameter
\c!distance
762
\egroup
763
\nobreak
764
\fi
}
765 766
% this needs a further cleanup ... soon as it's a slow mechanism
767
%
768
% -- set breakpoint in descriptions
769
% -- reset after trialtypesetting
770
% -- that way we can trick the symbol space
771 772
% removed:
773
%
774
% \pushsomestates
775
%
776
% core-ins -> obsolete
777
%
778
% saveinsertiondata
779
% restoreinsertiondata
780
% saveinsertionbox
781
% eraseinsertionbackup
782
% restoreinsertionbackup
783 784
\def
\savenotedata
{}
% \writestatus{todo}{save note data}}
785
\def
\restorenotedata
{}
% \writestatus{todo}{restore note data}}
786
\def
\savenotecontent
{}
% \writestatus{todo}{save note content}}
787
\def
\restorenotecontent
{}
% \writestatus{todo}{restore note content}}
788
\def
\erasenotebackup
{}
% \writestatus{todo}{erase note backup}}
789 790
% page-set:
791 792
\def
\enablenotes
{
\writestatus
{
todo
}{
enable
notes
}}
793
\def
\disablenotes
{
\writestatus
{
todo
}{
disable
notes
}}
794
\def
\savenotes
{
\writestatus
{
todo
}{
save
notes
}}
795
\def
\flushsavednotes
{
\writestatus
{
todo
}{
flush
notes
}}
796 797
% experiment: (compare scope=text and scope=page)
798
%
799
% \definenote[mynote][way=bytext,location=text,width=\leftmarginwidth,scope=page,rule=,before=,after=,factor=0]
800
% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][]
801 802
%D Footnotes are can be characterized by three components:
803
%D
804
%D \startitemize[packed]
805
%D \item a small number \footnote {a footnote number} or
806
%D symbol {\setupfootnotes [conversion=set 2]\footnote
807
%D {a footnote}}
808
%D \item and a similar mark at the bottom of the page
809
%D \item followed by some additional text
810
%D \stopitemize
811
%D
812
%D Because footnotes are declared at the location of their
813
%D reference they can be seen as a special kind of
814
%D floating bodies. Their placement is postponed but has to be
815
%D taken into account in the pagebreak calculations. This kind
816
%D of calculations are forced by using \type{\insert}s and dealing
817
%D with all cases is not trivial.
818 819
%D \macros
820
%D {notesenabled}
821
%D
822
%D We need a couple of states because at some moments we don't want
823
%D to mess around with inserts at all. Take for instance a table
824
%D of contents. And so we can temporary disable footnotes by saying
825
%D
826
%D \starttyping
827
%D \notesenabledfalse
828
%D \stoptyping
829 830
\newif
\ifnotesenabled
\notesenabledtrue
831 832
% better mark a note .. once flushed no more flushing
833 834
%appendtoks \notesenabledfalse \to \everymarking
835
\appendtoks
\notesenabledfalse
\to
\everybeforepagebody
836
\appendtoks
\notesenabledfalse
\to
\everystructurelist
% quick hack
837
\appendtoks
\notesenabledfalse
\to
\everysimplifycommands
% quick hack
838
\appendtoks
\notesenabledfalse
\to
\everypreroll
% quick hack
839 840
%D Often we need to process the whole set of notes and to make that
841
%D fast, we use a token register:
842 843
% we have several synchronizers:
844
%
845
% - after a definition
846
% - after a specific setup
847
% - after a general setup (inheritance of dimensions)
848
% - just before a note is typeset
849 850
\newtoks
\t_strc_notes
851 852
\let
\strc_notes_process_list
\gobbleoneargument
853 854
\unexpanded
\def
\strc_notes_process
#
action
% argument is a \macro that uses \currentnote
855
{
\def
\strc_notes_process_list
##
1
{
\edef
\currentnote
{
##
1
}
\let
\currentdescription
\currentnote
#
action
}
%
856
\the
\t_strc_notes
}
857 858
\newtoks
\everychecknote
% just before a note is typeset
859
\newtoks
\everysynchronizenote
% after a general setup has happened
860 861
\appendtoks
862
\ifx
\currentnote
\empty
\else
863
\setupnotations
[
\currentnote
][]
% also a synchronize
864
\fi
865
\to
\everysynchronizenote
866 867
\def
\strc_notes_synchronize
868
{
\the
\everysynchronizenote
}
% we can speed this one up if needed by avoiding the commalist
869 870
\appendtoks
871
\strc_notes_process
\strc_notes_synchronize
872
\to
\everysetupnoteroot
873 874
\appendtoks
875
\the
\everysynchronizenote
876
\to
\everydefinenote
877 878
% \starttext
879
% text \startfootnote Test.\stopfootnote
880
% test \footnote{xxxx} \subfootnote{xxxx}
881
% test \footnote{xxxx} \subfootnote{xxxx}
882
% \stoptext
883 884
\installcorenamespace
{
notecommand
}
885
\installcorenamespace
{
notealign
}
886
\installcorenamespace
{
notepenalty
}
887
\installcorenamespace
{
noterule
}
888 889
\def
\currentnoterulecommand
{
\begincsname
\??notecommand
\currentnote
\endcsname
}
890
\def
\currentnoterulealign
{
\begincsname
\??notealign
\currentnote
\endcsname
}
891 892
\def
\currentnoterulecommandcommand
{
\noteparameter
\c!rulecommand
}
893
\def
\currentnoterulecommandnormal
{
\normalnoterule
}
% no let as it can be changed afterwards
894
%def\currentnoterulecommandunknown{\noteparameter\c!rule}
895 896
\def
\letcurrentnoterulecommand
{
\expandafter\let\csname
\??notecommand
\currentnote
\endcsname
}
897
\def
\letcurrentnoterulealign
{
\expandafter\let\csname
\??notealign
\currentnote
\endcsname
}
898 899
\appendtoks
900
\letvalue
{
\??notecommand
\currentnote
}
\currentnoterulecommandnormal
901
\letvalue
{
\??notealign
\currentnote
}
\lefttoright
902
\to
\everysynchronizenote
903 904
\def
\strc_notes_set_rule
905
{
\letcurrentnoterulecommand
\relax
% so we default to nothing
906
\letcurrentnoterulealign
\relax
907
\processcommacommand
[
\noteparameter
\c!rule
]
\strc_notes_set_rule_step
}
908 909
\def
\strc_notes_set_rule_step
#
alternative
%
910
{
\begincsname
\??noterule
#
alternative
\endcsname
}
911 912
\def
\strc_notes_set_rule_autodir
913
{
\doifelserighttoleftinbox
\currentnoteinsertionnumber
\righttoleft\lefttoright
}
914 915
\setvalue
{
\??noterule
\v!command
}{
\letcurrentnoterulecommand
\currentnoterulecommandcommand
}
916
\setvalue
{
\??noterule
\v!on
}{
\letcurrentnoterulecommand
\currentnoterulecommandnormal
}
917
\setvalue
{
\??noterule
\v!normal
}{
\letcurrentnoterulecommand
\currentnoterulecommandnormal
}
918
\setvalue
{
\??noterule
\v!left
}{
\letcurrentnoterulecommand
\currentnoterulecommandnormal
919
\letcurrentnoterulealign
\lefttoright
}
920
\setvalue
{
\??noterule
\v!right
}{
\letcurrentnoterulecommand
\currentnoterulecommandnormal
921
\letcurrentnoterulealign
\righttoleft
}
922
\setvalue
{
\??noterule\v!paragraph
}{
\letcurrentnoterulecommand
\currentnoterulecommandnormal
923
\letcurrentnoterulealign
\strc_notes_set_rule_autodir
}
924
\setvalue
{
\??noterule
\v!off
}{
\letcurrentnoterulecommand
\relax
}
925 926
\appendtoks
927
\strc_notes_set_rule
928
\to
\everysynchronizenote
929 930
\def
\currentnotepenalty
931
{
\ifcsname
\??notepenalty
\noteparameter
\c!split
\endcsname
932
\lastnamedcs
933
\else
934
\numexpr
\noteparameter
\c!split
\relax
935
\fi
}
936 937
\setnewconstant
\notepenaltytolerant
\zerocount
938
\setnewconstant
\notepenaltystrict
9
9
9
9
939
\setnewconstant
\notepenaltyverystrict
\maxdimen
940 941
\letvalue
{
\??notepenalty\v!tolerant
}
\notepenaltytolerant
942
\letvalue
{
\??notepenalty\v!strict
}
\notepenaltystrict
943
\letvalue
{
\??notepenalty\v!verystrict
}
\notepenaltyverystrict
944
\letvalue
{
\??notepenalty
}
\notepenaltytolerant
945 946
% \def\strc_notes_set_width
947
% {\edef\p_width{\noteparameter\c!width}%
948
% \ifx\p_width\empty
949
% \setnoteparameter\c!width{\hsize}%
950
% \fi}
951 952
\setupnotes
953
[
\c!width
=
\v!auto
]
954 955
\def
\strc_notes_set_width
956
{
\edef
\p_width
{
\noteparameter
\c!width
}
%
957
\ifx
\p_width
\v!auto
958
\setnoteparameter
\c!width
{
\ifdim
\hsize
<
\makeupwidth
\hsize\else
\makeupwidth
\fi
}
%
959
\else\ifx
\p_width
\empty
960
\setnoteparameter
\c!width
{
\hsize
}
%
961
\fi\fi
}
962 963
\appendtoks
964
\strc_notes_set_width
965
\to
\everysynchronizenote
966 967
%D The following switch can be used to disable limiting the height of the footnote
968
%D area, something that is needed in multi column balancing. Use this switch with
969
%D care.
970 971
\newif
\ifnotelimit
\notelimittrue
% shared
972 973
\def
\strc_notes_set_factor
974
{
\edef
\p_factor
{
\noteparameter
\c!factor
}
%
975
\ifx
\p_factor
\empty
\else
976
\ifnum
\p_factor
<
\zerocount
\else
977
% \global
978
\count
\currentnoteinsertionnumber
\p_factor
% new: global
979
\fi
980
\fi
}
981 982
\appendtoks
983
\strc_notes_set_factor
984
\to
\everysynchronizenote
985 986
% locations:
987 988
\installcorenamespace
{
notelocationvariant
}
989
\installcorenamespace
{
notepositionvariant
}
990
\installcorenamespace
{
notedelayedvariant
}
991
\installcorenamespace
{
notelocation
}
992 993
\newconditional
\c_strc_notes_delayed
994 995
\unexpanded
\def
\strc_notes_set_delayed_yes
{
\settrue
\c_strc_notes_delayed
}
996
\unexpanded
\def
\strc_notes_set_delayed_nop
{
\setfalse
\c_strc_notes_delayed
}
997 998
\setvalue
{
\??notelocation\v!page
}{
\letvalue
{
\??notedelayedvariant
\currentnote
}
\strc_notes_set_delayed_nop
999
\letvalue
{
\??notelocationvariant
\currentnote
}
\strc_notes_set_location_page
}
1000
\setvalue
{
\??notelocation\v!columns
}{
\letvalue
{
\??notedelayedvariant
\currentnote
}
\strc_notes_set_delayed_nop
1001
\letvalue
{
\??notelocationvariant
\currentnote
}
\strc_notes_set_location_columns
}
1002
\setvalue
{
\??notelocation\v!lastcolumn
}{
\letvalue
{
\??notedelayedvariant
\currentnote
}
\strc_notes_set_delayed_nop
1003
\letvalue
{
\??notelocationvariant
\currentnote
}
\strc_notes_set_location_lastcolumn
}
1004
\setvalue
{
\??notelocation\v!firstcolumn
}{
\letvalue
{
\??notedelayedvariant
\currentnote
}
\strc_notes_set_delayed_nop
1005
\letvalue
{
\??notelocationvariant
\currentnote
}
\strc_notes_set_location_firstcolumn
}
1006
\setvalue
{
\??notelocation\v!none
}{
\letvalue
{
\??notedelayedvariant
\currentnote
}
\strc_notes_set_delayed_yes
1007
\letvalue
{
\??notelocationvariant
\currentnote
}
\strc_notes_set_location_none
}
1008
\setvalue
{
\??notelocation\v!text
}{
\letvalue
{
\??notedelayedvariant
\currentnote
}
\strc_notes_set_delayed_yes
1009
\letvalue
{
\??notelocationvariant
\currentnote
}
\strc_notes_set_location_text
}
1010
\setvalue
{
\??notelocation\v!high
}{
\letvalue
{
\??notepositionvariant
\currentnote
}
\strc_notes_set_position_high
}
1011
\setvalue
{
\??notelocation\v!bottom
}{
\letvalue
{
\??notepositionvariant
\currentnote
}
\strc_notes_set_position_bottom
}
1012 1013
\setvalue
{
\??notedelayedvariant
\??notedelayedvariant
}{
\strc_notes_set_delayed_nop
}
% not let
1014
\setvalue
{
\??notepositionvariant\??notepositionvariant
}{
\strc_notes_set_position_bottom
}
% not let
1015
\setvalue
{
\??notelocationvariant\??notelocationvariant
}{
\strc_notes_set_location_page
}
% not let
1016 1017
\unexpanded
\def
\strc_notes_set_delayed
1018
{
\csname
\??notedelayedvariant
1019
\ifcsname
\??notedelayedvariant
\currentnote
\endcsname
1020
\currentnote
1021
\else
1022
\??notedelayedvariant
1023
\fi
1024
\endcsname
}
1025 1026
% \let\strc_notes_set_delayed_yes\truecondition
1027
% \let\strc_notes_set_delayed_nop\falsecondition
1028
%
1029
% \def\c_strc_notes_delayed
1030
% {\csname\??notedelayedvariant
1031
% \ifcsname\??notedelayedvariant\currentnote\endcsname
1032
% \currentnote
1033
% \else
1034
% \??notedelayedvariant
1035
% \fi
1036
% \endcsname}
1037 1038
\unexpanded
\def
\strc_notes_set_position
1039
{
\csname
\??notepositionvariant
1040
\ifcsname
\??notepositionvariant
\currentnote
\endcsname
1041
\currentnote
1042
\else
1043
\??notepositionvariant
1044
\fi
1045
\endcsname
}
1046 1047
\unexpanded
\def
\strc_notes_set_location
1048
{
\csname
\??notelocationvariant
1049
\ifcsname
\??notelocationvariant
\currentnote
\endcsname
1050
\currentnote
1051
\else
1052
\??notelocationvariant
1053
\fi
1054
\endcsname
}
1055 1056
\unexpanded
\def
\strc_notes_set_variants
1057
{
\normalexpanded
{
\rawprocesscommalist
[
\noteparameter
\c!location
]
\strc_notes_set_location_step
}}
1058 1059
\unexpanded
\def
\strc_notes_set_location_step
#
alternative
% the insert related one
1060
%{\ifcsname\??notelocation#alternative\endcsname\csname\??notelocation#alternative\endcsname\fi}
1061
{
\begincsname
\??notelocation
#
alternative
\endcsname
}
1062 1063
\appendtoks
1064
\strc_notes_set_variants
1065
\strc_notes_set_delayed
1066
\to
\everysynchronizenote
1067 1068
\newskip
\s_strc_notes_distance
% we need to implement stretch
1069
\newcount
\c_strc_notes_columns
1070 1071
\newskip
\s_strc_notes_before
1072
\newskip
\s_strc_notes_inbetween
1073
\newconditional
\c_strc_notes_first_flushed
1074 1075
\appendtoks
1076
\edef
\p_spacebefore
{
\rootnoteparameter
\c!spacebefore
}
%
1077
\ifx
\p_spacebefore
\empty
1078
\global
\s_strc_notes_before
\zeropoint
1079
\else
1080
\setbox
\scratchbox
\vbox
{
\blank
[
\p_spacebefore
]
\global
\s_strc_notes_before
\lastskip
}
%
1081
\fi
1082
\edef
\p_spaceinbetween
{
\rootnoteparameter
\c!spaceinbetween
}
%
1083
\ifx
\p_spaceinbetween
\empty
1084
\global
\s_strc_notes_inbetween
\zeropoint
1085
\else
1086
\setbox
\scratchbox
\vbox
{
\blank
[
\p_spaceinbetween
]
\global
\s_strc_notes_inbetween
\lastskip
}
%
1087
\fi
1088
\to
\everysynchronizenote
1089 1090
\def
\strc_notes_set_distance
1091
{
\begingroup
1092
\restoreglobalbodyfont
1093
\setbox
\scratchbox
\vbox
% no reuse as it can mirror
1094
{
\forgetall
1095
\dontcomplain
1096
\noteparameter
\c!before
1097
\placenoterule
1098
\strut
1099
\noteparameter
\c!after
}
%
1100
% also dp now
1101
\scratchdimen
\dimexpr
\htdp\scratchbox
-
\lineheight
\relax
1102
\ifgridsnapping
1103
\getnoflines
\scratchdimen
1104
\scratchdimen
\noflines
\lineheight
1105
\fi
1106
\expandafter\endgroup\expandafter
1107
\s_strc_notes_distance
\the
\scratchdimen
\relax
}
1108 1109
\def
\strc_notes_set_columns
1110
{
\c_strc_notes_columns
\noteparameter
\c!n
\relax
1111
\ifcase
\c_strc_notes_columns
1112
\c_strc_notes_columns
\plusone
1113
\fi
}
1114 1115
\def
\strc_notes_set_location_page
1116
{
\setfalse
\c_strc_notes_delayed
1117
\strc_notes_set_distance
1118
\strc_notes_set_columns
1119
\page_inserts_set_location
\currentnoteinsertion
\v!page
% \setupinsertion[\currentnote][\c!location=\v!page]%
1120
\global\count
\currentnoteinsertionnumber
\numexpr
\plusthousand
/
\c_strc_notes_columns
\relax
1121
\global\dimen
\currentnoteinsertionnumber
\ifnotelimit
\dimexpr
\noteparameter
\c!height
*
\c_strc_notes_columns
\relax\else
\maxdimen
\fi
1122
\global\skip
\currentnoteinsertionnumber
\s_strc_notes_distance
}
1123 1124
\def
\strc_notes_set_location_columns
1125
{
\setfalse
\c_strc_notes_delayed
1126
\strc_notes_set_distance
1127
\strc_notes_set_columns
1128
\ifnum
\currentnofcolumns
=
\zerocount
1129
\c_strc_notes_columns
\plusone
1130
\fi
1131
\page_inserts_set_location
\currentnoteinsertion
\v!columns
% \setupinsertion[\currentnote][\c!location=\v!columns]%
1132
\global\count
\currentnoteinsertionnumber
\numexpr
\plusthousand
/
\c_strc_notes_columns
\relax
1133
\global\dimen
\currentnoteinsertionnumber
\ifnotelimit
\dimexpr
\noteparameter
\c!height
*
\c_strc_notes_columns
\relax\else
\maxdimen
\fi
1134
\global\skip
\currentnoteinsertionnumber
\s_strc_notes_distance
}
1135 1136
\def
\strc_notes_set_location_somecolumn
#
whatcolumn
%
1137
{
\setfalse
\c_strc_notes_delayed
1138
\strc_notes_set_distance
1139
\strc_notes_set_columns
1140
\page_inserts_set_location
\currentnoteinsertion
#
whatcolumn
% \setupinsertion[\currentnote][\c!location=#whatcolumn]%
1141
\global\count
\currentnoteinsertionnumber
\plusthousand
1142
\global\dimen
\currentnoteinsertionnumber
\ifnotelimit
\noteparameter
\c!height
\else
\maxdimen
\fi
1143
\global\skip
\currentnoteinsertionnumber
\s_strc_notes_distance
}
1144 1145
\def
\strc_notes_set_location_firstcolumn
{
\strc_notes_set_location_somecolumn
\v!firstcolumn
}
1146
\def
\strc_notes_set_location_lastcolumn
{
\strc_notes_set_location_somecolumn
\v!lastcolumn
}
1147 1148
\def
\strc_notes_set_location_text
% we don't use inserts anyway (e.g. endnotes)
1149
{
\settrue
\c_strc_notes_delayed
1150
\clf_setnotestate
{
\currentnote
}{
store
}
%
1151
\page_inserts_set_location
\currentnoteinsertion
\v!text
% \setupinsertion[\currentnote][\c!location=\v!text]%
1152
\global\count
\currentnoteinsertionnumber
\zerocount
1153
\global\dimen
\currentnoteinsertionnumber
\maxdimen
1154
\global\skip
\currentnoteinsertionnumber
\zeropoint
}
1155 1156
\let
\strc_notes_set_location_none
\strc_notes_set_location_text
1157 1158
\def
\strc_notes_set_properties
1159
{
\strc_notes_set_columns
1160
\strc_notes_set_distance
1161
\strc_notes_set_location
1162
\strc_notes_set_delayed
}
1163 1164
\let
\strc_notes_set_position_high
\relax
1165 1166
\def
\strc_notes_set_position_bottom
1167
{
\settrue
\c_notes_bottom_present
}
1168 1169
\appendtoks
1170
\strc_notes_set_properties
1171
\to
\everysynchronizenote
1172 1173
%D A fast checker for bottom notes being used:
1174 1175
\newconditional
\c_notes_bottom_present
1176 1177
\def
\strc_notes_check_if_bottom_present_indeed
% in otr !
1178
{
\ifvoid
\currentnoteinsertionnumber
\else
1179
\strc_notes_set_position
1180
\fi
}
1181 1182
\def
\strc_notes_check_if_bottom_present_step
1183
{
\ifconditional
\c_notes_bottom_present
\else
\strc_notes_check_if_bottom_present_indeed
\fi
}
1184 1185
\def
\strc_notes_check_if_bottom_present
1186
{
\setfalse
\c_notes_bottom_present
1187
\strc_notes_process
\strc_notes_check_if_bottom_present_step
}
1188 1189
% Example of using factor:
1190
%
1191
% \definenote[mynote][way=bypage,location=text,width=\marginwidth,rule=,before=,factor=0]
1192
% \setuplayout[backspace=5cm,margin=3cm,margindistance=.5cm,width=middle]
1193
% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][]
1194
% \starttext
1195
% \dorecurse{10}{test \mynote{one one one one one one} \input zapf \mynote{one one one one one one} }
1196
% \stoptext
1197 1198
%D The noterule can be a graphic and therefore calling this
1199
%D setup macro at every skipswitch is tricky (many many MP
1200
%D runs). Let's just reserve a few points, that probably match
1201
%D those of the stretch component.
1202 1203
%D A bit messy:
1204 1205
\unexpanded
\def
\placenoterule
1206
{
\begingroup
1207
\currentnoterulealign
1208
\currentnoterulecommand
1209
\par
1210
\endgroup
}
1211 1212
\unexpanded
\def
\normalnoterule
1213
{
\ifvmode
1214
\dontleavehmode
\blackrule
1215
[
\c!color
=
\noteparameter
\c!rulecolor
,
1216
\c!width
=
.
2
\hsize
,
1217
\c!height
=
\noteparameter
\c!rulethickness
,
1218
\c!depth
=
\zeropoint
]
%
1219
\endgraf
1220
\kern
\strutdepth
1221
\fi
}
1222 1223
\ifdefined
\setnotehsize
\else
1224 1225
\unexpanded
\def
\setnotehsize
{
\hsize
\noteparameter
\c!width
\relax
}
% can be overloaded
1226 1227
\fi
1228 1229
%D The formatting depends on the width of the table, so we
1230
%D have to set \type {n} to zero.
1231
%D
1232
%D \starttyping
1233
%D \startbuffer
1234
%D \bTABLE
1235
%D \bTR \bTD one \footnote{\dorecurse{10}{abcd }} \eTD \bTD two \eTD \eTR
1236
%D \bTR \bTD three fout five six seven eight nine \eTD \bTD ten \eTD \eTR
1237
%D \eTABLE
1238
%D \stopbuffer
1239
%D
1240
%D \startlocalfootnotes[n=0,location={text,none}]
1241
%D \placelegend[n=2]{\getbuffer}{\placelocalfootnotes}
1242
%D \stoplocalfootnotes
1243
%D \stoptyping
1244 1245
%D \macros
1246
%D {footnote}
1247
%D
1248
%D A footnote can have a reference as optional argument and
1249
%D therefore its formal specification looks like:
1250
%D
1251
%D \showsetup{footnote}
1252
%D
1253
%D This command has one optional command: the reference. By
1254
%D saying \type{[-]} the number is omitted. The footnote
1255
%D command is not that sensitive to spacing, so it's quite
1256
%D legal to say:
1257
%D
1258
%D \startbuffer
1259
%D Users of \CONTEXT\ must keep both feet \footnote{Given they
1260
%D have two.} on the ground and not get confused \footnote{Or
1261
%D even crazy.} by all those obscure \footnote{But fortunately
1262
%D readable.} parameters.
1263
%D \stopbuffer
1264
%D
1265
%D \typebuffer
1266
%D
1267
%D When setting the \type{conversion} to \type{set 2} we get
1268
%D something like:
1269
%D
1270
%D \bgroup
1271
%D \startnarrower
1272
%D \setupfootnotes[conversion=set 1]
1273
%D \getbuffer
1274
%D \stopnarrower
1275
%D \egroup
1276
%D
1277
%D Typesetting footnotes is, at least for the moment, disabled
1278
%D when reshaping boxes.
1279
%D
1280
%D The additional macro \type {\footnotetext} and the
1281
%D associated \type {\note} macro were implemented at
1282
%D request of users on the mailing list and a suggestion by
1283
%D taco to split of the symbol placement. I decided to
1284
%D merge this functionality with the existing \type {\note}
1285
%D functionality.
1286 1287
\newconditional
\c_strc_notes_symbol
\settrue
\c_strc_notes_symbol
% not used
1288
\newconditional
\c_strc_notes_skip
1289 1290
\unexpanded
\def
\setnote
[#
tag
]
{
\csname
#
tag
\endcsname
}
1291
\unexpanded
\def
\setnotetext
[#
tag
]
{
\global
\settrue
\c_strc_notes_skip
\csname
#
tag
\endcsname
}
1292 1293
\unexpanded
\def
\handlenoteinsert
#
tag
#
id
%
1294
{
\begingroup
1295
\edef
\currentnote
{
#
tag
}
%
1296
\strc_constructions_initialize
{
#
tag
}
%
1297
\strc_notes_synchronize
1298
\the
\everybeforenoteinsert
1299
\insert
\currentnoteinsertionnumber
\bgroup
1300
\the
\everyinsidenoteinsert
\relax
1301
\usesetupsparameter
\noteparameter
% experimental
1302
\useinterlinespaceparameter
\noteparameter
1303
\doifelse
{
\noteparameter
\c!paragraph
}
\v!yes
1304
{
\nointerlineskip
1305
\startvboxtohboxseparator
1306
\noteparameter
\c!inbetween
1307
\stopvboxtohboxseparator
1308
\startvboxtohbox
1309
\handlenoteitself
{
#
tag
}{
#
id
}
%
1310
\stopvboxtohbox
}
1311
{
\handlenoteitself
{
#
tag
}{
#
id
}}
%
1312
\egroup
1313
\the
\everyafternoteinsert
1314
\endgroup
}
1315 1316
\unexpanded
\def
\betweennoteitself
#
tag
% used ?
1317
{
\edef
\currentnote
{
#
tag
}
%
1318
\doif
{
\noteparameter
\c!paragraph
}
\v!yes
{
\noteparameter
\c!inbetween
}}
1319 1320
\unexpanded
\def
\handlenoteitself
#
tag
#
id
%
1321
{
\edef
\currentnotenumber
{
#
id
}
%
1322
\edef
\currentnote
{
#
tag
}
%
1323
\strc_constructions_initialize
{
#
tag
}
%
1324
\strc_notes_synchronize
1325
\edef
\currentconstructionlistentry
{
\clf_notelistindex
{
\currentnote
}
#
id
}
% index in list cache
1326
% as we can have collected notes (e.g. in tables) we need to recover
1327
% \currentdescriptionattribute and \currentdescriptionsynchronize
1328
%
1329
\reinstatecachedconstructionnumberentry
\currentconstructionlistentry
% we could store the number in the entry (e.g. needed when local notes in table)
1330
%
1331
\dontcomplain
1332
%begingroup
1333
\strc_notes_interaction_check_display
1334
\strc_notes_set_reference_attribute_text
1335
\strc_constructions_stored_start
1336
\begstrut
1337
\strc_references_flush_destination_nodes
1338
\strc_notes_set_destination_attribute_text
1339
\strc_notes_inject_text
\relax
1340
\ifvmode
\obeydepth
\else
\endstrut
\fi
% \obeydepth is new per 2015-01-10
1341
\strc_constructions_stored_stop
1342
%endgroup
1343
}
1344 1345
\unexpanded
\def
\strc_notes_inject_text
% hm main?
1346
{
\clf_savedlisttitle
{
\currentconstructionmain
}
\currentconstructionlistentry
\relax
}
1347 1348
\let
\startpushnote
\relax
1349
\let
\stoppushnote
\relax
1350 1351
\newsignal
\notesignal
1352 1353
\newconditional
\processingnote
1354
\newconditional
\postponednote
1355 1356
\newtoks
\everybeforenoteinsert
1357
\newtoks
\everyinsidenoteinsert
1358
\newtoks
\everyafternoteinsert
1359 1360
\unexpanded
\def
\doifelseinnote
1361
{
\ifconditional
\processingnote
1362
\expandafter
\firstoftwoarguments
1363
\else
1364
\expandafter
\secondoftwoarguments
1365
\fi
}
1366 1367
\appendtoks
1368
\let
\flushnotes
\relax
1369
\let
\postponenotes
\relax
1370
\forgetall
1371
\resetallattributes
% new, we don't want color bleed into notes
1372
\inheritmaintextcolor
% but we do want to obey the textcolor
1373
\to
\everybeforenoteinsert
1374 1375
% \def\strc_notes_set_penalties
1376
% {\doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment
1377
% %\interlinepenalty\maxdimen % todo
1378
% \penalty\currentnotepenalty}
1379 1380
\def
\strc_notes_set_penalties
1381
{
% stored in insert node
1382
\floatingpenalty
\currentnotepenalty
1383
% used when typesetting
1384
\interlinepenalty
\plushundred
% plain value
1385
% used when we need to split in columns
1386
\ifnum
\noteparameter
\c!n
>
\plusone
1387
\penalty
\zerocount
% otherwise no split in columns, maybe just always (tex just adds it to accumulated)
1388
\fi
}
1389 1390
\appendtoks
1391
\strc_notes_set_penalties
1392
\forgetall
% again
1393
\strc_notes_set_bodyfont
1394
\redoconvertfont
% to undo \undo calls in in headings etc
1395
\splittopskip
\strutht
% not actually needed here
1396
\splitmaxdepth
\strutdp
% not actually needed here
1397
%
1398
% not:
1399
%
1400
% \leftmargindistance \noteparameter\c!margindistance
1401
% \rightmargindistance\leftmargindistance
1402
% \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ?
1403
% \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ?
1404
% \fi
1405
%
1406
\pickupattributes
1407
\to
\everyinsidenoteinsert
1408 1409
%D Nasty, the might be more:
1410 1411
\appendtoks
\strc_itemgroups_push
\to
\everybeforenoteinsert
1412
\appendtoks
\strc_itemgroups_pop
\to
\everyafternoteinsert
1413 1414
% maybe but better use [scope=local] here
1415
%
1416
% \appendtoks
1417
% \setfalse\inhibitmargindata
1418
% \to \everyinsidenoteinsert
1419 1420
\appendtoks
1421
% only needed when columns (could be three \set...)
1422
\setsimplecolumnshsize
[
\c!distance
=
\noteparameter
\c!columndistance
,
\c!n
=
\noteparameter
\c!n
,
\c!width
=
\noteparameter
\c!width
]
%
1423
\to
\everyinsidenoteinsert
1424 1425
% not: \appendtoks \setnotehsize \to \everyinsidenoteinsert (spoils columns)
1426 1427
%D Normally footnotes are saved as inserts that are called upon
1428
%D as soon as the pagebody is constructed. The footnote
1429
%D insertion routine looks just like the \PLAIN\ \TEX\ one,
1430
%D except that we check for the end note state.
1431 1432
% testcase for split bottom alignment see (a) below
1433
%
1434
% \dorecurse{6}{\input tufte\footnote{\input ward \input tufte \relax}}
1435 1436
\newconditional
\c_strc_notes_first_placed
1437 1438
\unexpanded
\def
\placenoteinserts
1439
{
\setfalse
\c_strc_notes_first_placed
1440
\strc_notes_process
\strc_notes_place_inserts
}
1441 1442
\def
\strc_notes_place_inserts
1443
{
\strc_notes_set_delayed
% \strc_notes_synchronize % we need to know if it's delayed
1444
\ifconditional
\c_strc_notes_delayed
\else
1445
\ifdim
\ht
\currentnoteinsertionnumber
>
\zeropoint
% or a faster delayed test
1446
\strc_notes_place_inserts_indeed
1447
\settrue
\c_strc_notes_first_placed
1448
\fi
1449
\fi
}
1450 1451
\def
\strc_notes_place_inserts_indeed
1452
{
\relax
1453
\ifdim
\ht
\currentnoteinsertionnumber
>
\zeropoint
1454
\endgraf
1455
\ifvmode
1456
\whitespace
1457
\ifconditional
\c_strc_notes_first_placed
1458
\edef
\p_spaceinbetween
{
\noteparameter
\c!spaceinbetween
}
%
1459
\ifx
\p_spaceinbetween
\empty
\else
1460
\blank
[
\p_spaceinbetween
]
%
1461
\fi
1462
\else
1463
\edef
\p_spacebefore
{
\noteparameter
\c!spacebefore
}
%
1464
\ifx
\p_spacebefore
\empty
\else
1465
\blank
[
\p_spacebefore
]
%
1466
\fi
1467
\fi
1468
\noteparameter
\c!before
1469
\fi
1470
\placenoterule
1471
\bgroup
1472
\strc_notes_set_bodyfont
1473
\setbox
\scratchbox
\hbox
1474
{
\strc_notes_flush_inserts
}
%
1475
\page_postprocessors_linenumbers_deepbox
\scratchbox
1476
\setbox
\scratchbox
\hbox
1477
{
\setupcurrentnote
1478
[
\c!location
=
,
1479
\c!width
=
\v!fit
,
1480
\c!height
=
\v!fit
,
1481
\c!strut
=
\v!no
,
1482
\c!offset
=
\v!overlay
]
%
1483
\inheritednoteframed
1484
{
\ifzeropt
\dp
\scratchbox
% this hack is needed because \vadjust
1485
\hpack
{
\lower
\strutdp
\box
\scratchbox
}
% % in margin number placement
1486
\else
% hides the (always) present depth
1487
\box
\scratchbox
1488
\fi
}}
%
1489
\setbox
\scratchbox
\hpack
{
\lower
\strutdepth
\box
\scratchbox
}
%
1490
\dp
\scratchbox
\strutdepth
% so we know that it has the note bodyfont depth
1491
\ifvmode
1492
\nointerlineskip
% else sometimes empty line
1493
\fi
1494
\box
\scratchbox
1495
\egroup
1496
\endgraf
1497
\ifvmode
1498
\noteparameter
\c!after
1499
\fi
1500
\fi
}
1501 1502
\def
\strc_notes_flush_inserts
1503
{
\ifcase
\noteparameter
\c!n
\relax
1504
% should not happen
1505
\or
1506
\strc_notes_flush_inserts_normal
1507
\else
1508
\strc_notes_flush_inserts_columns
1509
\fi
}
1510 1511
\def
\strc_notes_flush_inserts_normal
1512
{
\strc_notes_flush_global
1513
\obeydepth
}
% (a) added , since split footnotes will not align properly
1514 1515
\def
\strc_notes_flush_inserts_columns
1516
{
\startsimplecolumns
[
\c!distance
=
\noteparameter
\c!columndistance
,
\c!n
=
\noteparameter
\c!n
,
\c!width
=
\noteparameter
\c!width
]
%
1517
\strc_notes_flush_global
1518
\stopsimplecolumns
}
1519 1520
% idea: tag with attr and then just flush them again
1521 1522
\def
\strc_notes_flush_global
1523
{
\begingroup
1524
\useinterlinespaceparameter
\noteparameter
1525
\doifelse
{
\noteparameter
\c!paragraph
}
\v!yes
1526
{
\leftorrightvbox
% cf mail from ws to list
1527
{
\starthboxestohbox
1528
\iftrialtypesetting
\unvcopy\else\unvbox\fi
\currentnoteinsertionnumber
1529
\stophboxestohbox
}}
1530
{
\iftrialtypesetting
\unvcopied
\else
\unvboxed
\fi
\currentnoteinsertionnumber
}
%
1531
\endgroup
}
1532 1533
%D Supporting end notes is surprisingly easy. Even better, we
1534
%D can combine this feature with solving the common \TEX\
1535
%D problem of disappearing inserts when they're called for in
1536
%D deeply nested boxes. The general case looks like:
1537
%D
1538
%D \starttyping
1539
%D \postponenotes
1540
%D \.box{whatever we want with footnotes}
1541
%D \flushnotes
1542
%D \stoptyping
1543
%D
1544
%D This alternative can be used in headings, captions, tables
1545
%D etc. The latter one sometimes calls for notes local to
1546
%D the table, which can be realized by saying
1547
%D
1548
%D \starttyping
1549
%D \setlocalfootnotes
1550
%D some kind of table with local footnotes
1551
%D \placelocalfootnotes
1552
%D \stoptyping
1553
%D
1554
%D Postponing is accomplished by simply redefining the (local)
1555
%D insert operation. A not too robust method uses the
1556
%D \type{\insert} primitive when possible. This method fails in
1557
%D situations where it's not entirely clear in what mode \TEX\
1558
%D is. Therefore the auto method can is to be overruled when
1559
%D needed.
1560 1561
\newconditional
\postponingnotes
1562 1563
% we need a proper state: normal, postponing, flushing
1564 1565
\unexpanded
\def
\postponenotes
1566
{
\ifconditional
\postponingnotes
\else
1567
\global
\settrue
\postponingnotes
1568
\glet
\flushnotes
\doflushnotes
1569
\clf_postponenotes
1570
\fi
}
1571 1572
\let
\flushnotes
\relax
1573 1574
\unexpanded
\def
\startpostponingnotes
% experimental, page-mix
1575
{
\ifconditional
\postponingnotes
\else
1576
\global
\settrue
\postponingnotes
1577
%\glet\flushnotes\doflushnotes
1578
\clf_postponenotes
1579
\fi
}
1580 1581
\unexpanded
\def
\stoppostponingnotes
% experimental, page-mix
1582
{
\doflushnotes
}
1583 1584
\unexpanded
\def
\doflushnotes
1585
{
\ifconditional
\postponingnotes
1586
\begingroup
1587
\let
\flushnotes
\relax
1588
\let
\postponenotes
\relax
1589
\ifconditional
\postponednote
1590
\ifhmode
1591
% needed for tagging ... otherwise we get some weird node free error
1592
\signalcharacter
1593
\fi
1594
\fi
1595
\clf_flushpostponednotes
% this also resets the states !
1596
\global
\setfalse
\postponednote
1597
\global
\setfalse
\postponingnotes
1598
\glet
\flushnotes
\relax
1599
\endgroup
1600
\fi
}
1601 1602
%D \macros
1603
%D {startlocalfootnotes,placelocalfootnotes}
1604
%D
1605
%D The next two macros can be used in for instance tables, as
1606
%D we'll demonstrate later on.
1607
%D
1608
%D \showsetup{startlocalfootnotes}
1609
%D \showsetup{placelocalfootnotes}
1610 1611
% todo: compatibility mode: when first arg is assignment or missing, then all
1612 1613
\newtoks
\everyplacelocalnotes
1614 1615
\appendtoks
1616
\let
\flushnotes
\relax
1617
\let
\postponenotes
\relax
1618
\to
\everyplacelocalnotes
1619 1620
\newconditional
\inlocalnotes
1621 1622
\unexpanded
\def
\startlocalnotes
1623
{
\dosingleempty
\strc_notes_local_start
}
1624 1625
\def
\strc_notes_local_start
[#
list
]
% grouping ? (we used to have a second argument ... settings)
1626
{
\def
\localnoteslist
{
#
list
}
%
1627
\settrue
\inlocalnotes
1628
\processcommacommand
[
\localnoteslist
]
\strc_notes_local_start_step
}
1629 1630
\unexpanded
\def
\stoplocalnotes
1631
{
\processcommacommand
[
\localnoteslist
]
\strc_notes_local_stop_step
1632
\setfalse
\inlocalnotes
}
1633 1634
\let
\p_strc_notes_continue
\empty
1635 1636
\def
\strc_notes_local_start_step
#
tag
%
1637
{
\p_strc_notes_continue
{
\noteparameter
\c!continue
}
%
1638
\ifx
\p_strc_notes_continue
\v!yes
\else
1639
\strc_counters_save
{
#
tag
}
%
1640
\strc_counters_reset
{
#
tag
}
%
1641
\fi
1642
\clf_savenote
{
#
tag
}{
store
}}
1643 1644
\def
\strc_notes_local_stop_step
#
tag
%
1645
{
\p_strc_notes_continue
{
\noteparameter
\c!continue
}
%
1646
\ifx
\p_strc_notes_continue
\v!yes
\else
1647
\strc_counters_restore
{
#
tag
}
%
1648
\fi
1649
\clf_restorenote
{
#
tag
}}
1650 1651
\unexpanded
\def
\placelocalnotes
1652
{
\dodoubleempty
\strc_notes_local_place
}
1653 1654
\def
\strc_notes_local_place
[#
tag
][#
settings
]
%
1655
{
\doif
{
\clf_getnotestate
{
#
tag
}}{
store
}{
\strc_notes_local_place_indeed
{
#
settings
}{
#
tag
}}}
1656 1657
\def
\strc_notes_local_place_indeed
#
settings
#
tag
%
1658
{
\begingroup
1659
\edef
\currentnote
{
#
tag
}
% is already set?
1660
\the
\everyplacelocalnotes
1661
% beware, we cannot trust setting \currentnote here
1662
\setupcurrentnote
[#
settings
]
% later we set height etc for framed
1663
\strc_notes_place_local_alternative
1664
\strc_notes_set_properties
% restore globals (if needed)
1665
\endgroup
1666
}
% TODO: just restore properties \the\everychecknote} % we need to restore the old state
1667 1668
%D These commands can be used like:
1669
%D
1670
%D \startbuffer
1671
%D \startlocalnotes[footnote]
1672
%D \placetable
1673
%D {Some Table}
1674
%D \placeontopofeachother
1675
%D {\starttable[|l|r|]
1676
%D \HL
1677
%D \VL Nota\footnote{Bene} \VL Bene\footnote{Nota} \VL\SR
1678
%D \VL Bene\footnote{Nota} \VL Nota\footnote{Bene} \VL\SR
1679
%D \HL
1680
%D \stoptable}
1681
%D {\setupnotation[footnote][alternative={serried},distance=.5em,after=\hskip1em]%
1682
%D \placelocalnotes[footnote]}
1683
%D \stoplocalnotes
1684
%D \stopbuffer
1685
%D
1686
%D \typebuffer
1687
%D
1688
%D Because this table placement macro expect box content, and
1689
%D thanks to the grouping of the local footnotes, we don't need
1690
%D additional braces.
1691
%D
1692
%D \getbuffer
1693 1694
%D \macros
1695
%D {placefootnotes}
1696
%D
1697
%D We still have no decent command for placing footnotes
1698
%D somewhere else than at the bottom of the page (for which no
1699
%D user action is needed). Footnotes (endnotes) can be
1700
%D placed by using
1701
%D
1702
%D \showsetup{placefootnotes}
1703 1704
\unexpanded
\def
\placebottomnotes
1705
{
\strc_notes_process
\strc_notes_place_inserts
}
1706 1707
\unexpanded
\def
\placenotes
1708
{
\dodoubleempty
\strc_notes_place
}
1709 1710
\def
\strc_notes_place
[#
list
][#
settings
]
%
1711
{
\processcommalist
[#
list
]
{
\strc_notes_place_indeed
{
#
settings
}}}
1712 1713
\def
\strc_notes_place_indeed
#
settings
#
tag
% settings note
1714
{
\edef
\currentnote
{
#
tag
}
% grouping ?
1715
\doifelse
{
\clf_getnotestate
{
#
tag
}}{
store
}
1716
\strc_notes_local_place_indeed
1717
\strc_notes_global_place_indeed
1718
{
#
settings
}{
#
tag
}}
1719 1720
\def
\strc_notes_global_place_indeed
#
settings
#
tag
%
1721
{
\begingroup
1722
\setupnote
[#
tag
][#
settings
]
%
1723
\strc_notes_place_inserts
1724
\endgroup
1725
\the
\everysetupnote
}
% to be checked .. synchronize
1726 1727
%D Placement
1728 1729
\installcorenamespace
{
notealternative
}
1730 1731
\unexpanded
\def
\installnotealternative
#
alternative
#
command
%
1732
{
\setvalue
{
\??notealternative
#
alternative
}{
#
command
}}
1733 1734
\unexpanded
\def
\doifnotescollected
#
tag
%
1735
{
\clf_doifnotecontent
{
#
tag
}}
1736 1737
\def
\strc_notes_place_local_alternative
% will be a setup (wrapper)
1738
{
\doifnotescollected
\currentnote
1739
{
\endgraf
1740
\ifvmode
1741
\whitespace
1742
\noteparameter
\c!before
1743
\fi
1744
\begingroup
1745
\strc_notes_set_bodyfont
1746
\csname
\??notealternative
\noteparameter
\c!alternative
\endcsname
1747
\endgroup
1748
\ifvmode
1749
\noteparameter
\c!after
1750
\fi
}}
1751 1752
%D A stupid alternative is also provided:
1753
%D
1754
%D \starttyping
1755
%D \setupfootnotes[location=text,alternative=none]
1756
%D \stoptyping
1757 1758
% setups ?
1759 1760
\def
\flushlocalnotes
#
tag
{
\clf_flushnotes
{
#
tag
}{
store
}{
\noteparameter
\c!criterium
}}
1761 1762
\installnotealternative
\v!none
1763
{
\flushlocalnotes
\currentnote
}
1764 1765
\installnotealternative
\empty
1766
{
\flushlocalnotes
\currentnote
}
1767 1768
\installnotealternative
\v!grid
% test if n > 0
1769
{
\begingroup
1770
\setupcurrentnote
[
\c!location
=]
%
1771
\snaptogrid
\hbox
1772
{
\inheritednoteframed
1773
{
\flushlocalnotes
\currentnote
}}
%
1774
\endgroup
}
1775 1776
\installnotealternative
\v!fixed
% test if n > 0
1777
{
\begingroup
1778
\setupcurrentnote
[
\c!location
=]
%
1779
\inheritednoteframed
1780
{
\flushlocalnotes
\currentnote
}
%
1781
\endgroup
}
1782 1783
\installnotealternative
\v!columns
% redundant
1784
{
\begingroup
1785
\setupcurrentnote
[
\c!location
=]
%
1786
\inheritednoteframed
1787
{
\edef
\currentnotewidth
{
\noteparameter
\c!width
}
%
1788
\doifelsedimension
\currentnotewidth
\donothing
1789
{
\edef
\currentnotewidth
{
\the\hsize
}}
%
1790
\startsimplecolumns
[
\c!distance
=
\noteparameter
\c!columndistance
,
\c!n
=
\noteparameter
\c!n
,
\c!width
=
\currentnotewidth
]
%
1791
\flushlocalnotes
\currentnote
1792
\stopsimplecolumns
}
%
1793
\endgroup
}
1794 1795
% 0:page 1:firstcolumn 2:lastcolumn
1796 1797
\newconstant
\c_strc_notes_page_location
1798 1799
\unexpanded
\def
\strc_notes_check_locations
1800
{
\edef
\p_strc_notes_location
{
\rootnoteparameter
\c!location
}
%
1801
\c_strc_notes_page_location
1802
\ifx
\p_strc_notes_location
\v!firstcolumn
\plusone
\else
1803
\ifx
\p_strc_notes_location
\v!lastcolumn
\plustwo
\else
1804
\zerocount
\fi\fi
}
1805 1806
\appendtoks
1807
\strc_notes_check_locations
1808
\to
\everysynchronizenote
1809 1810
% still semi public (but will change)
1811 1812
\newif
\ifnotespresent
1813 1814
\unexpanded
\def
\checknotepresence
1815
{
\notespresentfalse
1816
\strc_notes_process
\strc_notes_check_presence
}
1817 1818
\def
\strc_notes_check_presence
1819
{
\ifdim
\ht
\currentnoteinsertionnumber
>
\zeropoint
1820
\notespresenttrue
1821
\fi
}
1822 1823
%D \macros
1824
%D {fakenotes}
1825 1826
% used in page-mul
1827 1828
\ifdefined
\currentnofcolumns
\else
\def
\currentnofcolumns
{
\nofcolumns
}
\fi
1829 1830
\unexpanded
\def
\fakenotes
1831
{
\ifhmode
\endgraf
\fi\ifvmode
1832
\calculatetotalclevernoteheight
1833
\ifdim
\totalnoteheight
>
\zeropoint
\kern
\totalnoteheight
\fi
1834
\fi
}
1835 1836
\unexpanded
\def
\fakepagenotes
1837
{
\ifhmode
\endgraf
\fi\ifvmode
1838
\calculatetotalpagenoteheight
1839
\ifdim
\totalnoteheight
>
\zeropoint
\kern
\totalnoteheight
\fi
1840
\fi
}
1841 1842
% used in page-not but not yet ok
1843 1844
\newdimen
\totalnoteheight
1845 1846
\unexpanded
\def
\additionaltotalnoteheight
#
insert
% temp hacks anyway
1847
{
\dimexpr
1848
\ifdim
\ht
#
insert
>
\zeropoint
1849
\ifcase
\count
#
insert
%
1850
\zeropoint
1851
\else
% todo: divide by count
1852
\ht
#
insert
+
\skip
#
insert
% hm, no stretch but a dimen anyway
1853
\fi
1854
\else
1855
\zeropoint
1856
\fi
1857
\relax
}
1858 1859
\def
\docalculatetotalnoteheight
1860
{
\ifcase
\c_strc_notes_page_location
% tricky here ! ! ! to be sorted out ! ! !
1861
\advance
\totalnoteheight
\normalexpanded
{
\additionaltotalnoteheight
\currentnoteinsertionnumber
}
%
1862
\fi
}
1863 1864
\def
\docalculatetotalclevernoteheight
1865
{
\ifcase
\c_strc_notes_page_location
\else
% tricky here ! ! ! to be sorted out ! ! !
1866
\advance
\totalnoteheight
\normalexpanded
{
\additionaltotalnoteheight
\currentnoteinsertionnumber
}
%
1867
\fi
}
1868 1869
\def
\docalculatetotalpagenoteheight
1870
{
\advance
\totalnoteheight
\normalexpanded
{
\additionaltotalnoteheight
\currentnoteinsertionnumber
}}
1871 1872
\def
\calculatetotalnoteheight
{
\totalnoteheight
\zeropoint
\strc_notes_process
\docalculatetotalnoteheight
}
1873
\def
\calculatetotalclevernoteheight
{
\totalnoteheight
\zeropoint
\strc_notes_process
\docalculatetotalclevernoteheight
}
1874
\def
\calculatetotalpagenoteheight
{
\totalnoteheight
\zeropoint
\strc_notes_process
\docalculatetotalpagenoteheight
}
1875 1876
%D Now how can this mechanism be hooked into \CONTEXT\ without
1877
%D explictly postponing footnotes? The solution turned out to
1878
%D be rather simple:
1879
%D
1880
%D \starttyping
1881
%D \everypar {...\flushnotes...}
1882
%D \neverypar {...\postponenotes}
1883
%D \stoptyping
1884
%D
1885
%D We can use \type{\neverypar} because in most commands
1886
%D sensitive to footnote gobbling we disable \type{\everypar}
1887
%D in favor for \type{\neverypar}. In fact, this footnote
1888
%D implementation is the first to use this scheme.
1889 1890
%D This is a nasty and new secondary footnote flusher. It
1891
%D can be hooked into \type {\everypar} like:
1892
%D
1893
%D \starttyping
1894
%D \appendtoks \synchronizenotes \to \everypar
1895
%D \stoptyping
1896 1897
% \def\dosynchronizenotes
1898
% {\ifvoid\currentnoteinsertionnumber\else\insert\currentnoteinsertionnumber{\unvbox\currentnoteinsertionnumber}\fi}
1899
%
1900
% \def\synchronizenotes
1901
% {\strc_notes_process\dosynchronizenotes}
1902 1903
\let
\synchronizenotes
\relax
1904 1905
%D When typesetting footnotes, we have to return to the
1906
%D footnote specific bodyfont size, which is in most cases derived
1907
%D from the global document bodyfont size. In the previous macros
1908
%D we already used a footnote specific font setting macro.
1909 1910
\def
\strc_notes_set_bodyfont
1911
{
\let
\strc_notes_set_bodyfont
\relax
1912
\restoreglobalbodyfont
1913
\usebodyfontparameter
\noteparameter
1914
\usealignparameter
\noteparameter
}
1915 1916
%D The footnote mechanism defaults to a traditional one
1917
%D column way of showing them. By default we precede them by
1918
%D a small line.
1919 1920
\definenote
[
\v!footnote
]
1921
\definenote
[
\v!endnote
]
[
\c!location
=
\v!none
]
% else no break
1922 1923
%D Compatibility macros:
1924 1925
\unexpanded
\def
\setupfootnotedefinition
{
\setupnotation
[
\v!footnote
]
}
1926
\unexpanded
\def
\setupfootnotes
{
\setupnote
[
\v!footnote
]
}
1927
\def
\footnotetext
{
\setnotetext
[
\v!footnote
]
}
1928
\unexpanded
\def
\placefootnotes
{
\dodoubleempty
\strc_notes_place_footnotes
[
\v!footnote
]
}
1929
\unexpanded
\def
\placelocalfootnotes
{
\dodoubleempty
\strc_notes_place_local_footnotes
[
\v!footnote
]
}
1930
\unexpanded
\def
\startlocalfootnotes
{
\startlocalnotes
[
\v!footnote
]
}
% alleen footnote
1931
\unexpanded
\def
\stoplocalfootnotes
{
\stoplocalnotes
}
1932 1933
\def
\strc_notes_place_footnotes
[#
list
][#
settings
]
%
1934
{
\ifsecondargument
1935
\placenotes
[#
list
][#
settings
,
\c!height
=
\textheight
]
%
1936
\else
1937
\placenotes
[#
list
][
\c!height
=
\textheight
]
%
1938
\fi
}
1939 1940
\def
\strc_notes_place_local_footnotes
[#
list
][#
settings
]
%
1941
{
\ifsecondargument
1942
\placelocalnotes
[#
list
][#
settings
,
\c!height
=
\textheight
]
%
1943
\else
1944
\placelocalnotes
[#
list
][
\c!height
=
\textheight
]
%
1945
\fi
}
1946 1947
%D Goodies:
1948
%D
1949
%D \starttyping
1950
%D \dorecurse {100} {
1951
%D test \footnote{\doifnoteonsamepageelse[footnote]{ibidem}{aaa}}
1952
%D }
1953
%D \stoptyping
1954 1955
\def
\doifelsenoteonsamepage
#
tag
{
\clf_doifnoteonsamepageasprevious
{
#
tag
}}
1956 1957
\let
\doifnoteonsamepageelse\doifelsenoteonsamepage
1958 1959
%D New trickery:
1960 1961
%D \macros
1962
%D {note}
1963
%D
1964
%D Refering to a note is accomplished by the rather short
1965
%D command:
1966
%D
1967
%D \showsetup{note}
1968
%D
1969
%D This command is implemented rather straightforward as:
1970 1971
\installcorenamespace
{
notesymbol
}
1972 1973
\let
\lastnotesymbol
\relax
% todo: per class
1974 1975
\unexpanded
\def
\notesymbol
1976
{
\dodoubleempty
\strc_notes_symbol
}
1977 1978
\def
\strc_notes_symbol
[#
tag
][#
reference
]
%
1979
{
\ifnotesenabled
1980
\dontleavehmode
1981
\begingroup
1982
\edef
\currentnote
{
#
tag
}
%
1983
\usenotestyleandcolor
\c!textstyle\c!textcolor
1984
\ifsecondargument
1985
\unskip
1986
\noteparameter
\c!textcommand
{
\in
[#
reference
]
}
% command here?
1987
\else
1988
\noteparameter
\c!textcommand
\lastnotesymbol
% check if command double
1989
\fi
1990
\endgroup
1991
\fi
}
1992 1993
\unexpanded
\def
\note
1994
{
\dodoubleempty
\strc_notes_note
}
1995 1996
\def
\strc_notes_note
[#
tag
][#
reference
]
%
1997
{
\ifsecondargument
1998
\strc_notes_symbol
[#
tag
][#
reference
]
%
1999
\else
2000
\secondargumenttrue
2001
\strc_notes_symbol
[
\v!footnote
][#
tag
]
%
2002
\fi
}
2003 2004
% will be redone if needed
2005
%
2006
% \def\ownnotesymbol#1% #1 gets number passed
2007
% {\executeifdefined{\??notesymbol\currentnote}\empty}
2008
%
2009
% \unexpanded\def\setnotesymbol[#1]#2#3%
2010
% {\prewordbreak % prevent lookback
2011
% \setgvalue{\??notesymbol#1}{#3}
2012
% \strc_notes_inject_symbol}
2013
%
2014
% \unexpanded\def\ownnote[#1]#2#3#4%
2015
% {\setnotesymbol[#1]{#2}{#3}%
2016
% \setnotetext [#1]{#4}}
2017
%
2018
% \defineconversion
2019
% [ownnote]
2020
% [\ownnotesymbol]
2021 2022
% tricky:
2023
%
2024
% \enabletrackers[nodes.areas]
2025
% \enabletrackers[nodes.references]
2026
% \enabletrackers[nodes.destinations]
2027
%
2028
% \setupnotes[interaction=all,rule=no]
2029
% \setupinteraction[state=start,focus=standard]
2030
%
2031
% \starttext
2032
% \goto{\input tufte\relax}[page(2)] \par
2033
% \ruledhbox{\gotobox{\vtop{\input tufte\relax}}[page(2)]} \par
2034
% \ruledhbox{\gotobox{\vbox{\input tufte\relax}}[page(2)]} \par
2035
% % \completecontent
2036
% % \chapter{Chapter}
2037
% % \dorecurse{5}{\input knuth}
2038
% a\footnote{\input tufte\par\input ward\relax}
2039
% \stoptext
2040 2041
\protect
\endinput
2042 2043