-
Notifications
You must be signed in to change notification settings - Fork 26
/
siunitx-unit.dtx
3023 lines (3023 loc) · 102 KB
/
siunitx-unit.dtx
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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% \iffalse meta-comment
%
% File: siunitx-unit.dtx Copyright (C) 2014-2024 Joseph Wright
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version. The latest version
% of this license is in the file
%
% https://www.latex-project.org/lppl.txt
%
% This file is part of the "siunitx bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% The released version of this bundle is available from CTAN.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
% https://github.com/josephwright/siunitx
%
% for those people who are interested.
%
% -----------------------------------------------------------------------
%
%<*driver>
\documentclass{l3doc}
% Additional commands needed in this source
\ExplSyntaxOn
\makeatletter
\NewDocumentCommand \acro { m }
{
\textsc
{
\exp_args:NV \tl_if_head_eq_charcode:nNTF \f@series { m }
{ \text_lowercase:n }
{ \use:n }
{#1}
}
}
\makeatother
\ExplSyntaxOff
\ProvideDocumentCommand\email{m}{\href{mailto:#1}{\nolinkurl{#1}}}
\ProvideDocumentCommand\foreign{m}{\textit{#1}}
% The next line is needed so that \GetFileInfo will be able to pick up
% version data
\usepackage{siunitx}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \GetFileInfo{siunitx.sty}
%
% \title{^^A
% \pkg{siunitx-unit} -- Parsing and formatting units^^A
% \thanks{This file describes \fileversion,
% last revised \filedate.}^^A
% }
%
% \author{^^A
% Joseph Wright^^A
% \thanks{^^A
% E-mail:
% \email{[email protected]}^^A
% }^^A
% }
%
% \date{Released \filedate}
%
% \maketitle
%
% \begin{documentation}
%
% This submodule is dedicated to formatting physical units. The main function,
% \cs{siunitx_unit_format:nN}, takes user input specifying physical units and
% converts it into a formatted token list suitable for typesetting in math
% mode. While the formatter will deal correctly with \enquote{literal} user
% input, the key strength of the module is providing a method to describe
% physical units in a \enquote{symbolic} manner. The output format of these
% symbolic units can then be controlled by a number of key--value options
% made available by the module.
%
% A small number of \LaTeXe{} math mode commands are assumed to be available
% as part of the formatted output. The \cs{mathchoice} command
% (normally the \TeX{} primitive) is needed when using different settings
% for inline and display |per-mode|. The commands \cs{frac}, \cs{mathrm},
% \cs{mbox}, \verb*|\ | and \cs{,} are used by the standard module settings.
% For the display of colored (highlighted) and cancelled units, the commands
% \cs{textcolor} and \cs{cancel} are assumed to be available.
%
% \section{Formatting units}
%
% \begin{function}{\siunitx_unit_format:nN, \siunitx_unit_format:VN}
% \begin{syntax}
% \cs{siunitx_unit_format:nN} \Arg{units} \meta{tl~var}
% \end{syntax}
% This function converts the input \meta{units} into a processed
% \meta{tl~var} which can then be inserted in math mode to typeset the
% material. Where the \meta{units} are given in symbolic form, described
% elsewhere, this formatting process takes place in two stages: the
% \meta{units} are parsed into a structured form before the generation
% of the appropriate output form based on the active settings. When the
% \meta{units} are given as literals, processing is minimal: the
% characters |.| and |~| are converted to unit products (boundaries).
% In both cases, the result is a series of tokens intended to be typeset
% in math mode with appropriate choice of font for typesetting of the
% textual parts.
%
% For example,
% \begin{verbatim}
% \siunitx_unit_format:nN { \kilo \metre \per \second } \l_tmpa_tl
% \end{verbatim}
% will, with standard settings, result in \cs{l_tmpa_tl} being set to
% \begin{verbatim}
% \mathrm{km}\,\mathrm{s}^{-1}
% \end{verbatim}
% \end{function}
%
% \begin{function}{\siunitx_unit_format_extract_prefixes:nNN}
% \begin{syntax}
% \cs{siunitx_unit_format_extract_prefixes:nNN} \Arg{units} \meta{tl~var} \meta{fp~var}
% \end{syntax}
% This function formats the \meta{units} in the same way as described for
% \cs{siunitx_unit_format:nN}. When the input is given in symbolic form,
% any decimal unit prefixes will be extracted and the overall power of
% ten that these represent will be stored in the \meta{fp~var}.
%
% For example,
% \begin{verbatim}
% \siunitx_unit_format_extract_prefixes:nNN { \kilo \metre \per \second }
% \l_tmpa_tl \l_tmpa_fp
% \end{verbatim}
% will, with standard settings, result in \cs{l_tmpa_tl} being set to
% \begin{verbatim}
% \mathrm{m}\,\mathrm{s}^{-1}
% \end{verbatim}
% with \cs{l_tmpa_fp} taking value~$3$. Note that the latter is a floating
% point variable: it is possible for non-integer values to be obtained here.
% \end{function}
%
% \begin{function}{\siunitx_unit_format_combine_exponent:nnN}
% \begin{syntax}
% \cs{siunitx_unit_format_combine_exponent:nnN} \Arg{units} \Arg{exponent} \meta{tl~var}
% \end{syntax}
% This function formats the \meta{units} in the same way as described for
% \cs{siunitx_unit_format:nN}. The \meta{exponent} is combined with any
% prefix for the \emph{first} unit of the \meta{units}, and an updated
% prefix is introduced.
%
% For example,
% \begin{verbatim}
% \siunitx_unit_format_combine_exponent:nnN { \metre \per \second }
% { 3 } \l_tmpa_tl
% \end{verbatim}
% will, with standard settings, result in \cs{l_tmpa_tl} being set to
% \begin{verbatim}
% \mathrm{km}\,\mathrm{s}^{-1}
% \end{verbatim}
% \end{function}
%
% \begin{function}
% {
% \siunitx_unit_format_multiply:nnN ,
% \siunitx_unit_format_multiply_extract_prefixes:nnNN ,
% \siunitx_unit_format_multiply_combine_exponent:nnnN
% }
% \begin{syntax}
% \cs{siunitx_unit_format_multiply:nnN} \Arg{units} \Arg{factor} \meta{tl~var}
% \cs{siunitx_unit_format_multiply_extract_prefixes:nnNN}
% \Arg{units} \Arg{factor} \meta{tl~var} \meta{fp~var}
% \cs{siunitx_unit_format_multiply_combine_exponent:nnnN}
% \Arg{units} \Arg{factor} \Arg{exponent} \meta{tl~var}
% \end{syntax}
% These function formats the \meta{units} in the same way as described for
% \cs{siunitx_unit_format:nN}. The units are multiplied by the \meta{factor},
% and further processing takes place as previously described.
%
% For example,
% \begin{verbatim}
% \siunitx_unit_format_multiply:nnN { \metre \per \second }
% { 3 } \l_tmpa_tl
% \end{verbatim}
% will, with standard settings, result in \cs{l_tmpa_tl} being set to
% \begin{verbatim}
% \mathrm{km}^{3}\,\mathrm{s}^{-3}
% \end{verbatim}
% \end{function}
%
% \section{Defining symbolic units}
%
% \begin{function}{\siunitx_declare_prefix:Nnn, \siunitx_declare_prefix:Nne}
% \begin{syntax}
% \cs{siunitx_declare_prefix:Nnn} \meta{prefix} \Arg{power} \Arg{symbol}
% \end{syntax}
% Defines a symbolic \meta{prefix} (which should be a control sequence
% such as |\kilo|) to be converted by the parser to the \meta{symbol}.
% The latter should consist of literal content (\foreign{e.g.}~|k|).
% In literal mode the \meta{symbol} will be typeset directly. The prefix
% should represent an integer \meta{power} of $10$, and this information
% may be used to convert from one or more \meta{prefix} symbols to an
% overall power applying to a unit. See also
% \cs{siunitx_declare_prefix:Nn}.
% \end{function}
%
% \begin{function}{\siunitx_declare_prefix:Nn}
% \begin{syntax}
% \cs{siunitx_declare_prefix:Nn} \meta{prefix} \Arg{symbol}
% \end{syntax}
% Defines a symbolic \meta{prefix} (which should be a control sequence
% such as |\kilo|) to be converted by the parser to the \meta{symbol}.
% The latter should consist of literal content (\foreign{e.g.}~|k|).
% In literal mode the \meta{symbol} will be typeset directly. In contrast
% to \cs{siunitx_declare_prefix:Nnn}, there is no assumption about the
% mathematical nature of the \meta{prefix}, \foreign{i.e.}~the prefix may
% represent a power of any base. As a result, no conversion of the
% \meta{prefix} to a numerical power will be possible.
% \end{function}
%
% \begin{function}{\siunitx_declare_power:NNn}
% \begin{syntax}
% \cs{siunitx_declare_power:NNn} \meta{pre-power} \meta{post-power} \Arg{value}
% \end{syntax}
% Defines \emph{two} symbolic \meta{powers} (which should be control
% sequences such as |\squared|) to be converted by the parser to the
% \meta{value}. The latter should be an integer or floating point number in
% the format defined for \pkg{l3fp}. Powers may precede a unit or be give
% after it: both forms are declared at once, as indicated by the argument
% naming. In literal mode, the \meta{value} will be applied as
% a superscript to either the next token in the input (for the
% \meta{pre-power}) or appended to the previously-typeset material
% (for the \meta{post-power}).
% \end{function}
%
% \begin{function}{\siunitx_declare_qualifier:Nn}
% \begin{syntax}
% \cs{siunitx_declare_qualifier:Nn} \meta{qualifier} \Arg{meaning}
% \end{syntax}
% Defines a symbolic \meta{qualifier} (which should be a control sequence
% such as |\catalyst|) to be converted by the parser to the \meta{meaning}.
% The latter should consist of literal content (\foreign{e.g.}~|cat|). In
% literal mode the \meta{meaning} will be typeset following a space after
% the unit to which it applies.
% \end{function}
%
% \begin{function}
% {
% \siunitx_declare_unit:Nn,
% \siunitx_declare_unit:Ne,
% \siunitx_declare_unit:Nnn,
% \siunitx_declare_unit:Nen
% }
% \begin{syntax}
% \cs{siunitx_declare_unit:Nn} \meta{unit} \Arg{meaning}
% \cs{siunitx_declare_unit:Nnn} \meta{unit} \Arg{meaning} \Arg{options}
% \end{syntax}
% Defines a symbolic \meta{unit} (which should be a control sequence
% such as |\kilogram|) to be converted by the parser to the \meta{meaning}.
% The latter may consist of literal content (\foreign{e.g.}~|kg|), other
% symbolic unit commands (\foreign{e.g.}~|\kilo\gram|) or a mixture of the two.
% In literal mode the \meta{meaning} will be typeset directly. The version
% taking an \meta{options} argument may be used to support per-unit
% options: these are applied at the top level or using
% \cs{siunitx_unit_options_apply:n}.
% \end{function}
%
% \begin{variable}{\l_siunitx_unit_font_tl}
% The font function which is applied to the text of units when constructing
% formatted units: set by |font-command|.
% \end{variable}
%
% \begin{variable}{\l_siunitx_unit_fraction_tl}
% The fraction function which is applied when constructing fractional units:
% set by |fraction-command|.
% \end{variable}
%
% \begin{variable}{\l_siunitx_unit_symbolic_seq}
% This sequence contains all of the symbolic names defined:
% these will be in the form of control sequences such as |\kilogram|.
% The order of the sequence is unimportant. This includes prefixes and
% powers as well as units themselves.
% \end{variable}
%
% \begin{variable}{\l_siunitx_unit_seq}
% This sequence contains all of the symbolic \emph{unit} names defined:
% these will be in the form of control sequences such as |\kilogram|.
% In contrast to \cs{l_siunitx_unit_symbolic_seq}, it \emph{only} holds
% units themselves
% \end{variable}
%
% \section{Per-unit options}
%
% \begin{function}{\siunitx_unit_options_apply:n}
% \begin{syntax}
% \cs{siunitx_unit_options_apply:n} \meta{unit(s)}
% \end{syntax}
% Applies any unit-specific options set up using
% \cs{siunitx_declare_unit:Nnn}. This allows there use outside of unit
% formatting, for example to influence spacing in quantities. The options
% are applied only once at a given group level, which allows for user
% over-ride \foreign{via} |\keys_set:nn { siunitx } { ... }|.
% \end{function}
%
% \section{Units in (PDF) strings}
%
% \begin{function}{\siunitx_unit_pdfstring_context:}
% \begin{syntax}
% \cs{group_begin:}
% \cs{siunitx_unit_pdfstring_context:}
% \meta{Expansion context} \meta{units}
% \cs{group_end:}
% \end{syntax}
% Sets symbol unit macros to generate text directly. This is needed in
% expansion contexts where units must be converted to simple text. This
% function is itself not expandable, so must be using within a
% surrounding group as show in the example.
% \end{function}
%
% \section{Pre-defined symbolic unit components}
%
% The unit parser is defined to recognise a number of pre-defined units,
% prefixes and powers, and also interpret a small selection of
% \enquote{generic} symbolic parts.
%
% Broadly, the pre-defined units are those defined by the \textsc{bipm} in the
% documentation for the \emph{International System of Units}
% (\acro{SI})~\cite{BIPM}. As far as possible, the names given to the command
% names for units are those used by the \acro{bipm}, omitting spaces and using
% only \acro{ASCII} characters. The standard symbols are also taken from the
% same documentation. In the following documentation, the order of the
% description of units broadly follows the \acro{SI}~Brochure.
%
% \begin{function}
% {
% \kilogram ,
% \metre ,
% \meter ,
% \mole ,
% \kelvin ,
% \candela ,
% \second ,
% \ampere
% }
% The base units as defined in the \acro{SI} Brochure~\cite{base-units}.
% Notice that \cs{meter} is defined as an alias for \cs{metre} as the former
% spelling is common in the US (although the latter is the official spelling).
% \end{function}
%
% \begin{function}{\gram}
% The base unit \cs{kilogram} is defined using an \acro{SI} prefix: as such
% the (derived) unit \cs{gram} is required by the module to correctly produce
% output for the \cs{kilogram}.
% \end{function}
%
% \begin{function}
% {
% \quecto ,
% \ronto ,
% \yocto ,
% \zepto ,
% \atto ,
% \femto ,
% \pico ,
% \nano ,
% \micro ,
% \milli ,
% \centi ,
% \deci ,
% \deca ,
% \deka ,
% \hecto ,
% \kilo ,
% \mega ,
% \giga ,
% \tera ,
% \peta ,
% \exa ,
% \zetta ,
% \yotta ,
% \ronna ,
% \quetta
% }
% Prefixes, all of which are integer powers of $10$: the powers are stored
% internally by the module and can be used for conversion from prefixes to
% their numerical equivalent. These prefixes are documented in Section~3.1
% of the \acro{SI}~Brochure.
%
% Note that the \cs{kilo} prefix is required to
% define the base \cs{kilogram} unit. Also note the two spellings available
% for \cs{deca}/\cs{deka}.
% \end{function}
%
% \begin{function}
% {
% \becquerel ,
% \degreeCelsius ,
% \coulomb ,
% \farad ,
% \gray ,
% \hertz ,
% \henry ,
% \joule ,
% \katal ,
% \lumen ,
% \lux ,
% \newton ,
% \ohm ,
% \pascal ,
% \radian ,
% \siemens ,
% \sievert ,
% \steradian ,
% \tesla ,
% \volt ,
% \watt ,
% \weber
% }
% The defined \acro{SI}~units with defined names and symbols, as given in
% Table~4 of the \acro{SI}~Brochure. Notice that the names
% of the units are lower case with the exception of \cs{degreeCelsius}, and
% that this unit name includes \enquote{degree}.
% \end{function}
%
% \begin{function}
% {
% \astronomicalunit ,
% \bel ,
% \dalton ,
% \day ,
% \decibel ,
% \electronvolt ,
% \hectare ,
% \hour ,
% \litre ,
% \liter ,
% \neper ,
% \minute ,
% \tonne
% }
% Units accepted for use with the \acro{SI}: here \cs{minute} is a unit of
% time not of plane angle. These units are taken from Table~8 of the
% \acro{SI}~Brochure.
%
% For the unit \cs{litre}, both |l| and |L| are listed
% as acceptable symbols: the latter is the standard setting of the module.
% The alternative spelling \cs{liter} is also given for this unit for US
% users (as with \cs{metre}, the official spelling is \enquote{re}).
% \end{function}
%
% \begin{function}
% {
% \arcminute ,
% \arcsecond ,
% \degree
% }
% Units for plane angles accepted for use with the \acro{SI}: to avoid a
% clash with units for time, here \cs{arcminute} and \cs{arcsecond} are
% used in place of \cs{minute} and \cs{second}. These units are taken from
% Table~8 of the \acro{SI}~Brochure.
% \end{function}
%
% \begin{function}{\percent}
% The mathematical concept of percent, usable with the \acro{SI} as detailed
% in Section~5.4.7 of the \acro{SI}~Brochure.
% \end{function}
%
% \begin{function}{\square, \cubic}
% \begin{syntax}
% \cs{square} \meta{prefix} \meta{unit}
% \cs{cubic} \meta{prefix} \meta{unit}
% \end{syntax}
% Pre-defined unit powers which apply to the next \meta{prefix}/\meta{unit}
% combination.
% \end{function}
%
% \begin{function}{\squared, \cubed}
% \begin{syntax}
% \meta{prefix} \meta{unit} \cs{squared}
% \meta{prefix} \meta{unit} \cs{cubed}
% \end{syntax}
% Pre-defined unit powers which apply to the preceding
% \meta{prefix}/\meta{unit} combination.
% \end{function}
%
% \begin{function}{\per}
% \begin{syntax}
% \cs{per} \meta{prefix} \meta{unit} \meta{power}
% \end{syntax}
% Indicates that the next \meta{prefix}/\meta{unit}/\meta{power} combination
% is reciprocal, \foreign{i.e.}~raises it to the power $-1$. This symbolic
% representation may be applied in addition to a \cs{power}, and will work
% correctly if the \cs{power} itself is negative. In literal mode \cs{per}
% will print a slash (\enquote{$/$}).
% \end{function}
%
% \begin{function}{\cancel}
% \begin{syntax}
% \cs{cancel} \meta{prefix} \meta{unit} \meta{power}
% \end{syntax}
% Indicates that the next \meta{prefix}/\meta{unit}/\meta{power} combination
% should be \enquote{cancelled out}. In the parsed output, the entire unit
% combination will be given as the argument to a function \cs{cancel}, which
% is assumed to be available at a higher level. In literal mode, the same
% higher-level \cs{cancel} will be applied to the next token. It is the
% responsibility of the calling code to provide an appropriate definition
% for \cs{cancel} outside of the scope of the unit parser.
% \end{function}
%
% \begin{function}{\highlight}
% \begin{syntax}
% \cs{highlight} \Arg{color} \meta{prefix} \meta{unit} \meta{power}
% \end{syntax}
% Indicates that the next \meta{prefix}/\meta{unit}/\meta{power} combination
% should be highlighted in the specified \meta{color}. In the parsed output,
% the entire unit combination will be given as the argument to a function
% \cs{textcolor}, which is assumed to be available at a higher level. In
% literal mode, the same higher-level \cs{textcolor} will be applied to the
% next token. It is the responsibility of the calling code to provide an
% appropriate definition for \cs{textcolor} outside of the scope of the unit
% parser.
% \end{function}
%
% \begin{function}{\of}
% \begin{syntax}
% \meta{prefix} \meta{unit} \meta{power} \cs{of} \Arg{qualifier}
% \end{syntax}
% Indicates that the \meta{qualifier} applies to the current
% \meta{prefix}/\meta{unit}/\meta{power} combination. In parsed mode, the
% display of the result will depend upon module options. In literal mode,
% the \meta{qualifier} will be printed in parentheses following the preceding
% \meta{unit} and a full-width space.
% \end{function}
%
% \begin{function}{\raiseto, \tothe}
% \begin{syntax}
% \cs{raiseto} \Arg{power} \meta{prefix} \meta{unit}
% \meta{prefix} \meta{unit} \cs{tothe} \Arg{power}
% \end{syntax}
% Indicates that the \meta{power} applies to the current
% \meta{prefix}/\meta{unit} combination. As shown, \cs{raiseto} applies to
% the next \meta{unit} whereas \cs{tothe} applies to the preceding unit. In
% literal mode the \cs{power} will be printed as a superscript attached to
% the next token (\cs{raiseto}) or preceding token (\cs{tothe}) as
% appropriate.
% \end{function}
%
% \subsection{Key--value options}
%
% The options defined by this submodule are available within the \pkg{l3keys}
% |siunitx| tree.
%
% \begin{function}{bracket-unit-denominator}
% \begin{syntax}
% |bracket-unit-denominator| = |true|\verb"|"|false|
% \end{syntax}
% Switch to determine whether brackets are added to the denominator part of
% a unit when printed using inline fractional form (with |per-mode| as
% |repeated-symbol| or |symbol|). The standard setting is |true|.
% \end{function}
%
% \begin{function}{extract-mass-in-kilograms}
% \begin{syntax}
% |extract-mass-in-kilograms| = |true|\verb"|"|false|
% \end{syntax}
% Determines whether prefix extraction treats kilograms as a base unit; when
% set |false|, grams are used. The standard setting is |true|.
% \end{function}
%
% \begin{function}{forbid-literal-units}
% \begin{syntax}
% |forbid-literal-units| = |true|\verb"|"|false|
% \end{syntax}
% Switch which determines if literal units are allowed when parsing is
% active; does not apply when |parse-units| is |false|.
% \end{function}
%
% \begin{function}{fraction-command}
% \begin{syntax}
% |fraction-command| = \meta{command}
% \end{syntax}
% Command used to create fractional output when |per-mode| is set to
% |fraction|. The standard setting is |\frac|.
% \end{function}
%
% \begin{function}{inter-unit-product}
% \begin{syntax}
% |inter-unit-product| = \meta{separator}
% \end{syntax}
% Inserted between unit combinations in parsed mode, and used to replace
% |.| and |~| in literal mode. The standard setting is |\,|.
% \end{function}
%
% \begin{function}{parse-units}
% \begin{syntax}
% |parse-units| = |true|\verb"|"|false|
% \end{syntax}
% Determines whether parsing of unit symbols is attempted or literal
% mode is used directly. The standard setting is |true|.
% \end{function}
%
% \begin{function}{per-mode, inline-per-mode, display-per-mode}
% \begin{syntax}
% |per-mode| = |fraction|\verb"|"|power|\verb"|"|power-positive-first|\verb"|"|repeated-symbol|\verb"|"|single-symbol|\verb"|"|symbol|
% \end{syntax}
% Selects how the negative powers (\cs{per}) are formatted: a choice from
% the options |fraction|, |power|, |power-positive-first|, |repeated-symbol|,
% |single-symbol| and |symbol|. The option |fraction|
% generates fractional output when appropriate using the command specified by
% the |fraction-command| option. The setting |power| uses reciprocal powers
% leaving the units in the order of input, while |power-positive-first| uses
% the same display format but sorts units such that the positive powers
% come before negative ones. The |symbol| setting uses a symbol (specified
% by |per-symbol|) between positive and negative powers, while
% |repeated-symbol| uses the same symbol but places it before \emph{every}
% unit with a negative power (this is mathematically \enquote{wrong} but
% often seen in real work). The option |single-symbol| will use a symbol if
% exactly one is required (\foreign{i.e.}~with a single negative power), and
% will otherwise use powers. The standard setting is |power|.
%
% The |inline-...| and |display-...| settings take the same options and work
% in exactly the same way, but are restricted in where they apply. The
% |display| version only applies in display math contexts, and the |inline|
% version applies in all others.
% \end{function}
%
% \begin{function}{per-symbol}
% \begin{syntax}
% |per-symbol| = \meta{symbol}
% \end{syntax}
% Specifies the symbol to be used to denote negative powers when the option
% |per-mode| is set to |repeated-symbol| or |symbol|. The standard setting
% is |/|.
% \end{function}
%
% \begin{function}{per-symbol-script-correction}
% \begin{syntax}
% |per-symbol-script-correction| = \meta{insert}
% \end{syntax}
% Specifies the tokens used to correct spacing when the symbol set by
% |per-symbol| is immediately preceded by a superscript power. The
% standard setting is |\!|.
% \end{function}
%
% \begin{function}{power-half-as-sqrt}
% \begin{syntax}
% |power-half-as-sqrt| = |true|\verb"|"|false|
% \end{syntax}
% Used to determine whether a power of exactly half is converted to
% \cs{sqrt} in the output. The standard setting is |false|.
% \end{function}
%
% \begin{function}{qualifier-mode}
% \begin{syntax}
% |qualifier-mode| = |bracket|\verb"|"|combine|\verb"|"|phrase|\verb"|"|subscript|
% \end{syntax}
% Selects how qualifiers are formatted: a choice from the options |bracket|,
% |combine|, |phrase| and |subscript|. The option |bracket| wraps the qualifier
% in parenthesis, |combine| joins the qualifier with the unit directly, |phrase|
% joins the material using |qualifier-phrase| as a link, and
% |subscript| formats the qualifier as a subscript. The standard setting is
% |subscript|.
% \end{function}
%
% \begin{function}{qualifier-phrase}
% \begin{syntax}
% |qualifier-phrase| = \meta{phrase}
% \end{syntax}
% Defines the \meta{phrase} used when |qualifier-mode| is set to |phrase|.
% \end{function}
%
% \begin{function}{sticky-per}
% \begin{syntax}
% |sticky-per| = |true|\verb"|"|false|
% \end{syntax}
% Used to determine whether \cs{per} should be applied one a unit-by-unit
% basis (when |false|) or should apply to all following units
% (when |true|). The latter mode is somewhat akin conceptually to the
% \TeX{} \cs{over} primitive. The standard setting is |false|.
% \end{function}
%
% \begin{function}{unit-font-command}
% \begin{syntax}
% |unit-font-command| = \meta{command}
% \end{syntax}
% Command applied to text during output of units: should be command usable
% in math mode for font selection. Notice that in a typical unit this does
% not (necessarily) apply to all output, for example powers or brackets.
% The standard setting is |\mathrm|.
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{siunitx-unit} implementation}
%
% Start the \pkg{DocStrip} guards.
% \begin{macrocode}
%<*package>
% \end{macrocode}
%
% Identify the internal prefix.
% \begin{macrocode}
%<@@=siunitx_unit>
% \end{macrocode}
%
% \subsection{Initial set up}
%
% The mechanisms defined here need a few variables to exist and to be
% correctly set: these don't belong to one subsection and so are created
% in a small general block.
%
% Variants not provided by \pkg{expl3}.
% \begin{macrocode}
\cs_generate_variant:Nn \tl_replace_all:Nnn { NnV }
% \end{macrocode}
%
% \begin{variable}{\l_@@_tmp_bool}
% \begin{variable}{\l_@@_tmp_fp}
% \begin{variable}{\l_@@_tmp_int}
% \begin{variable}{\l_@@_tmp_tl}
% Scratch space.
% \begin{macrocode}
\bool_new:N \l_@@_tmp_bool
\fp_new:N \l_@@_tmp_fp
\int_new:N \l_@@_tmp_int
\tl_new:N \l_@@_tmp_tl
% \end{macrocode}
% \end{variable}
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}{\c_@@_math_subscript_tl}
% Useful tokens with awkward category codes.
% \begin{macrocode}
\tl_const:Nx \c_@@_math_subscript_tl
{ \char_generate:nn { `\_ } { 8 } }
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_parsing_bool}
% A boolean is used to indicate when the symbolic unit functions should
% produce symbolic or literal output. This is used when the symbolic names
% are used along with literal input, and ensures that there is a sensible
% fall-back for these cases.
% \begin{macrocode}
\bool_new:N \l_@@_parsing_bool
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_test_bool}
% A switch used to indicate that the code is testing the input to find
% if there is any typeset output from individual unit macros. This is needed
% to allow the \enquote{base} macros to be found, and also to pick up the
% difference between symbolic and literal unit input.
% \begin{macrocode}
\bool_new:N \l_@@_test_bool
% \end{macrocode}
% \end{variable}
%
% \begin{macro}{\@@_if_symbolic:nTF}
% The test for symbolic units is needed in two places. First, there is the
% case of \enquote{pre-parsing} input to check if it can be parsed. Second,
% when parsing there is a need to check if the current unit is built up
% from others (symbolic) or is defined in terms of some literals. To do this,
% the approach used is to set all of the symbolic unit commands expandable
% and to do nothing, with the few special cases handled manually. We expand
% the input here twice: this handles the case where there is a mapping or
% similar in |#1| which returns its result in \cs{exp_not:n}. In the second
% \tn{protected@edef}, changing the meaning of \tn{@unexpandable@protect}
% allows removal of a literal \cs{protect} at the top level before
% known symbolic entries: this deals with the case where the user has
% put in a \cs{protect} for some edge cases.
% \begin{macrocode}
\prg_new_protected_conditional:Npnn \@@_if_symbolic:n #1 { TF }
{
\group_begin:
\bool_set_true:N \l_@@_test_bool
\protected@edef \l_@@_tmp_tl {#1}
\cs_set_eq:NN \@@_saved_@unexpandable@protect: \@unexpandable@protect
\cs_set_nopar:Npn \@unexpandable@protect ##1
{
\cs_if_exist:cF { @@_ \token_to_str:N ##1 :w }
{ \@@_saved_@unexpandable@protect: }
##1
}
\protected@edef \l_@@_tmp_tl { \l_@@_tmp_tl }
\exp_args:NNV \group_end:
\tl_if_blank:nTF \l_@@_tmp_tl
{ \prg_return_true: }
{ \prg_return_false: }
}
% \end{macrocode}
% \end{macro}
%
% \subsection{Defining symbolic unit}
%
% Unit macros and related support are created here. These exist only within
% the scope of the unit processor code, thus not polluting document-level
% namespace and allowing overlap with other areas in the case of useful short
% names (for example \cs{pm}). Setting up the mechanisms to allow this requires
% a few additional steps on top of simply saving the data given by the user
% in creating the unit.
%
% \begin{variable}{\l_siunitx_unit_symbolic_seq}
% A list of all of the symbolic units, \foreign{etc.}, set up. This is needed
% to allow the symbolic names to be defined within the scope of the unit
% parser but not elsewhere using simple mappings.
% \begin{macrocode}
\seq_new:N \l_siunitx_unit_symbolic_seq
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_siunitx_unit_seq}
% A second list featuring only the units themselves.
% \begin{macrocode}
\seq_new:N \l_siunitx_unit_seq
% \end{macrocode}
% \end{variable}
%
% \begin{macro}{\@@_set_symbolic:Nnn}
% \begin{macro}{\@@_set_symbolic:Npnn}
% \begin{macro}{\@@_set_symbolic:Nnnn}
% The majority of the work for saving each symbolic definition is the same
% irrespective of the item being defined (unit, prefix, power, qualifier).
% This is therefore all carried out in a single internal function which
% does the common tasks. The three arguments here are the symbolic macro
% name, the literal output and the code to insert when doing full unit
% parsing. To allow for the \enquote{special cases} (where arguments are
% required) the entire mechanism is set up in a two-part fashion allowing
% for flexibility at the slight cost of additional functions.
%
% Importantly, notice that the unit macros are declared as expandable. This
% is required so that literals can be correctly converted into a token list
% of material which does not depend on local redefinitions for the unit
% macros. That is required so that the unit formatting system can be grouped.
% \begin{macrocode}
\cs_new_protected:Npn \@@_set_symbolic:Nnn #1
{ \@@_set_symbolic:Nnnn #1 { } }
\cs_new_protected:Npn \@@_set_symbolic:Npnn #1#2#
{ \@@_set_symbolic:Nnnn #1 {#2} }
\cs_new_protected:Npn \@@_set_symbolic:Nnnn #1#2#3#4
{
\seq_put_right:Nn \l_siunitx_unit_symbolic_seq {#1}
\cs_set:cpn { @@_ \token_to_str:N #1 :w } #2
{
\bool_if:NF \l_@@_test_bool
{
\bool_if:NTF \l_@@_parsing_bool
{#4}
{#3}
}
}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\siunitx_declare_power:NNn}
% Powers can come either before or after the unit. As they always come
% (logically) in matching, we handle this by declaring two commands,
% and setting each up separately.
% \begin{macrocode}
\cs_new_protected:Npn \siunitx_declare_power:NNn #1#2#3
{
\@@_set_symbolic:Nnn #1
{ \@@_literal_power:nn {#3} }
{ \@@_parse_power:nnN {#1} {#3} \c_true_bool }
\@@_set_symbolic:Nnn #2
{ ^ {#3} }
{ \@@_parse_power:nnN {#2} {#3} \c_false_bool }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\siunitx_declare_prefix:Nn}
% \begin{macro}{\siunitx_declare_prefix:Nnn, \siunitx_declare_prefix:Nne}
% \begin{variable}
% {\l_@@_prefixes_forward_prop, \l_@@_prefixes_reverse_prop}
% For prefixes there are a couple of options. In all cases, the basic
% requirement is to set up to parse the prefix using the appropriate
% internal function. For prefixes which are powers of $10$, there is also
% the need to be able to do conversion to/from the numerical equivalent.
% That is handled using two properly lists which can be used to supply
% the conversion data later.
% \begin{macrocode}
\cs_new_protected:Npn \siunitx_declare_prefix:Nn #1#2
{
\@@_set_symbolic:Nnn #1
{#2}
{ \@@_parse_prefix:Nn #1 {#2} }
}
\cs_new_protected:Npn \siunitx_declare_prefix:Nnn #1#2#3
{
\siunitx_declare_prefix:Nn #1 {#3}
\prop_put:Nnn \l_@@_prefixes_forward_prop {#3} {#2}
\prop_put:Nnn \l_@@_prefixes_reverse_prop {#2} {#3}
}
\cs_generate_variant:Nn \siunitx_declare_prefix:Nnn { Nne , Nnx }
\prop_new:N \l_@@_prefixes_forward_prop
\prop_new:N \l_@@_prefixes_reverse_prop
% \end{macrocode}
% \end{variable}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\siunitx_declare_qualifier:Nn}
% Qualifiers are relatively easy to handle: nothing to do other than save
% the input appropriately.
% \begin{macrocode}
\cs_new_protected:Npn \siunitx_declare_qualifier:Nn #1#2
{
\@@_set_symbolic:Nnn #1
{ ~ ( #2 ) }
{ \@@_parse_qualifier:nn {#1} {#2} }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\siunitx_declare_unit:Nn, \siunitx_declare_unit:Ne}
% \begin{macro}{\siunitx_declare_unit:Nnn, \siunitx_declare_unit:Nen}
% For the unit parsing, allowing for variations in definition order requires
% that a test is made for the output of each unit at point of use.
% \begin{macrocode}
\cs_new_protected:Npn \siunitx_declare_unit:Nn #1#2
{ \siunitx_declare_unit:Nnn #1 {#2} { } }
\cs_generate_variant:Nn \siunitx_declare_unit:Nn { Ne , Nx }
\cs_new_protected:Npn \siunitx_declare_unit:Nnn #1#2#3
{
\seq_put_right:Nn \l_siunitx_unit_seq {#1}
\@@_set_symbolic:Nnn #1
{#2}
{
\@@_if_symbolic:nTF {#2}
{#2}
{ \@@_parse_unit:Nn #1 {#2} }
}
\tl_clear_new:c { l_@@_options_ \token_to_str:N #1 _tl }
\tl_if_empty:nF {#3}
{ \tl_set:cn { l_@@_options_ \token_to_str:N #1 _tl } {#3} }
}
\cs_generate_variant:Nn \siunitx_declare_unit:Nnn { Ne , Nx }
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Applying unit options}
%
% \begin{variable}{\l_@@_options_bool}
% \begin{macrocode}
\bool_new:N \l_@@_options_bool
% \end{macrocode}
% \end{variable}
%
% \begin{macro}{\siunitx_unit_options_apply:n}
% Options apply only if they have not already been set at this group
% level.
% \begin{macrocode}
\cs_new_protected:Npn \siunitx_unit_options_apply:n #1
{
\bool_if:NF \l_@@_options_bool
{
\tl_if_single_token:nT {#1}
{
\tl_if_exist:cT { l_@@_options_ \token_to_str:N #1 _tl }
{
\keys_set:nv { siunitx }
{ l_@@_options_ \token_to_str:N #1 _tl }
}
}
}
\bool_set_true:N \l_@@_options_bool
}
% \end{macrocode}
% \end{macro}
%
% \subsection{Non-standard symbolic units}
%
% A few of the symbolic units require non-standard definitions: these are
% created here. They all use parts of the more general code but have particular
% requirements which can only be addressed by hand. Some of these could in
% principle be used in place of the dedicated definitions above, but at point
% of use that would then require additional expansions for each unit parsed:
% as the macro names would still be needed, this does not offer any real
% benefits.
%
% \begin{macro}{\per}
% The \cs{per} symbolic unit is a bit special: it has a mechanism entirely
% different from everything else, so has to be set up by hand. In literal
% mode it is represented by a very simple symbol!
% \begin{macrocode}
\@@_set_symbolic:Nnn \per
{ / }
{ \@@_parse_per: }
% \end{macrocode}
% \end{macro}