• No results found

Index of /CTAN/macros/latex/contrib/grading-scheme

N/A
N/A
Protected

Academic year: 2022

Share "Index of /CTAN/macros/latex/contrib/grading-scheme"

Copied!
45
0
0

Full text

(1)

The grading-scheme package

Maximilian Keßler

Released 2022/02/24

version 0.1.1

Abstract

This package aims at an easy-to-use interface to typeset grading schemes in tab- ular format, in particular grading-schemes of exercises of mathematical olympiads where multiple solutions have to be graded and might offer mutual exclusive ways of receiving points.

Contents

1 General notions 2

2 Usage 3

3 LATEX3 interface 4

Change History 5

4 grading-scheme implementation 5

4.1 Dependencies and options . . . 5

4.2 A simple logging module . . . 5

4.3 Wrappers . . . 6

4.4 Customizable backends . . . 7

4.5 Resources . . . 7

4.6 Pointers . . . 9

4.7 Structs . . . 15

4.8 Entries . . . 15

4.9 Blocks. . . 19

4.10 Elements . . . 28

4.11 Facilities for populating data structures . . . 34

4.12 Grading scheme environment . . . 36

4.13 Implementing the pipe syntax . . . 39

Index 40

[email protected]

(2)

sum

At least one correct solution 1 P.

All correct solutions 1 P.

max

Uniqueness proofs

max

First solution

sum

Show that either 4|p−2 or 3|p−4. 3 P.

Show thatm= 5 2 P.

Show thatn= 4 1 P.

Conclude solutions 1 P.

Second solution

sum

Show thatpis even 2 P.

Reduce to at most 30 candidates 3 P.

Test all candidates 2 P.

min(2)

Plausible Arguments

sum

plausible argument that there are finitely many solutions 1 P.

suggestion that divisibility by 4 is useful 1 P.

suggesting that not both ofm,ncan be ’large’. 1 P.

Table 1: Example output of a grading scheme.

1 General notions

Probably, an example is fitting best at this point. If you want to set up a grading scheme, with thegrading-scheme package all you have to do to get the output ofTable 1is type the following:

\begin{gradingscheme}{sum}

| At least one correct solution & 1

| All correct solutions & 1

\begin{block}{max}

\begin{block}[Uniqueness proofs]{max}

\begin{block}[First solution]{sum}

| Show that either $4 \mid p - 2$ or $3 \mid p - 4$. & 3

| Show that $m = 5$ & 2

| Show that $ n = 4 $ & 1

| Conclude solutions & 1

\end{block}

\begin{block}[Second solution]{sum}

| Show that $p$ is even & 2

| Reduce to at most 30 candidates & 3

| Test all candidates & 2

\end{block}

\end{block}

(3)

\begin{block}{min(2)}

\begin{block}[Plausible Arguments]{sum}

| plausible argument that there are finitely many solutions & 1

| suggestion that divisibility by 4 is useful & 1

| suggesting that not both of $m$, $n$ can be ’large’. & 1

\end{block}

\end{block}

\end{block}

\end{gradingscheme}

Note in particular that the correct width of the rows and columns are automatically adjusted.

For us, a grading scheme consists of several statements, each worth some specific number of points, that will be combined into a final number of points using a nested expression of operations, typically sums, maximums or minimus.

An abstract grammar defining our notions is defined in Table 2. The meanings of

⟨balanced text⟩and⟨number⟩are as usual.

grading scheme := block

block := [⟨block description⟩],⟨block operation⟩,⟨element list⟩

element list :=⟨element⟩ | ⟨element⟩: ⟨element list⟩

element :=⟨block⟩ | ⟨entry⟩

entry :=⟨entry description⟩, ⟨entry points⟩

block description :=⟨balanced text⟩

block operation :=⟨balanced text⟩

entry description :=⟨balanced text⟩

entry points :=⟨number⟩

Table 2: Abstract grammer for a grading scheme

The package facilitates specifying a grading scheme according to this grammar and typesets these.

2 Usage

Load the package as usual by

\usepackage[pipe]{grading-scheme}

Thepipe option is of course optional and the only currently supported option. It activates the pipe syntax explained later.

gradingscheme \begin{gradingscheme}[⟨description text⟩]{⟨operator⟩}

\end{gradingscheme}

The main environment provided by this package. Inside the grading scheme, any number of blocks and entries can be specified. The grading scheme environment will act like the outer-most block and typeset all its contents.

Grading schemes cannot contain each other. As they are implemented astabulars, you can (and maybe should) put a grading scheme into atableenvironment as if it were a regulartabular.

(4)

TEXhackers note: Actually, the gradingscheme environment just sets up some hooks that further block environments and entries will fill and typesets these at the end of the environment.

You could technically put any regular text inside the grading scheme and this will be typeset as if it had been specified before the grading scheme. However, this is definitely not recommended.

block \begin{block}[⟨description text⟩]{⟨operator⟩}

\end{block}

The⟨description text⟩will be shown in a separate row on top of the block. If not specfied, no such row is inserted. The⟨operator⟩is printed in small capitals (and rotated) in a column that spans the left side of the block, indicating that this operation is applied to the block.

The block will be an element of the outer block or grading scheme it is contained in.

Inside the block, any number of blocks or entries can be specified (in order) that will be typeset as members of this block.

A block environment can only be used inside a gradingscheme. Block environments can contain each other in balanced form.

\entry{⟨entry description⟩}{⟨points⟩}

Specifies an entry with given description and points. The entry is typeset as part of the block/grading scheme containing it.

\entry

| ⟨entry description⟩ & ⟨points⟩ \n

This is an alternative form to specify an entry. The\nis to be interpreted as a newline in the source file, so|reads until the end of the line.

This is equivalent to calling\entry{⟨entry description⟩}{⟨points⟩}

The package optionpipehas to be specified to activate this syntax.

TEXhackers note: The| character (pipe) is made an active character for the scope of each gradingscheme environment. Thus, this syntax only works if the gradingscheme is read in expansion mode by LATEX, since otherwise the category code will be messed up.

|

3 L

A

TEX3 interface

There is also a LATEX3 interface for dealing with this package that can deal with all of the mentioned notions separately, technically allowing you to combine them in other ways or formatting them into your custom tables.

These functions are for now not documented separately, since the author thinks that such use cases would be rather rare.

The LATEX3 interface is, however, not considered to be stable yet, so if you really have to rely on this, feel free to contact the author.

(5)

Change History

0.1

General: Initial release . . . 1 0.1.1

General: Bug fix (thanks to Denis

Bitouzé), typos. . . 1

4 grading-scheme implementation

1 ⟨∗package⟩

2 ⟨@@=grading_scheme⟩

4.1 Dependencies and options

Currently, there is only one option

\g__grading_scheme_pipe_syntax_bool This will toggle the pipe syntax option of the package.

3 \bool_new:N \g__grading_scheme_pipe_syntax_bool (End definition for\g__grading_scheme_pipe_syntax_bool.)

4 \keys_define:nn { grading-scheme }

5 {

6 pipe .bool_gset:N = \g__grading_scheme_pipe_syntax_bool,

7 pipe .default:n = { true },

8 unknown .code:n =

9 {

10 \msg_error:nnn { grading-scheme } { unknown-option} { \l_keys_key_str }

11 }

12 }

13 \msg_new:nnn { grading-scheme } { unknown-option}

14 {

15 Unknown ~ option ~ ’#1’.

16 }

17 \RequirePackage { l3keys2e }

18 \ProcessKeysOptions { grading-scheme }

19 \RequirePackage{multirow}

20 \RequirePackage{rotating}

4.2 A simple logging module

21 ⟨∗log⟩

We provide a simple log/debugging facility for this package.

\g__grading_scheme_log_depth_int Stores the log depth for indentation in the log file.

22 \int_new:N \g__grading_scheme_log_depth_int (End definition for\g__grading_scheme_log_depth_int.)

\__grading_scheme_log_incr: Increments the log depth

23 \cs_new:Npn \__grading_scheme_log_incr:

24 {

25 \int_gincr:N \g__grading_scheme_log_depth_int

26 }

(6)

(End definition for\__grading_scheme_log_incr:.)

\__grading_scheme_log_decr: Decrements the log depth

27 \cs_new:Npn \__grading_scheme_log_decr:

28 {

29 \int_gdecr:N \g__grading_scheme_log_depth_int

30 }

(End definition for\__grading_scheme_log_decr:.)

\__grading_scheme_log:n

\__grading_scheme_log:x

Logs to the terminal and log file using the current depth.

31 \cs_new:Npn \__grading_scheme_log:n #1

32 {

33 \iow_term:x

34 {

35 [gs] \prg_replicate:nn \g__grading_scheme_log_depth_int { . . }

36 \exp_not:n { #1 }

37 }

38 \iow_log:x

39 {

40 [gs] \prg_replicate:nn \g__grading_scheme_log_depth_int { . . }

41 \exp_not:n { #1 }

42 }

43 }

44 \cs_generate_variant:Nn \__grading_scheme_log:n { x } (End definition for\__grading_scheme_log:n.)

45 ⟨/log⟩

4.3 Wrappers

We provide some LATEX3 wrappers for private usage.

\__grading_scheme_multicolumn:nnn Just a wrapper around \multicolumnfrom LATEX 2ε.

46 \cs_set_eq:NN \__grading_scheme_multicolumn:nnn \multicolumn (End definition for\__grading_scheme_multicolumn:nnn.)

\__grading_scheme_multirow:nnn Just a wrapper around \multirowfrom LATEX 2ε.

47 \cs_set_eq:NN \__grading_scheme_multirow:nnn \multirow (End definition for\__grading_scheme_multirow:nnn.)

\__grading_scheme_cline:n

\__grading_scheme_cline:nn

A wrapper around\cline.

The second form takes the beginning and ending column as separate arguments.

48 \cs_set_eq:NN \__grading_scheme_cline:n \cline

49 \cs_new:Npn \__grading_scheme_cline:nn #1 #2

50 {

51 \__grading_scheme_cline:n { #1 - #2 }

52 }

(End definition for\__grading_scheme_cline:n and\__grading_scheme_cline:nn.)

(7)

\__grading_scheme_hline: Wrapper for a\hline

53 \cs_set_eq:NN \__grading_scheme_hline: \hline (End definition for\__grading_scheme_hline:.)

\__grading_scheme_rotatebox:nnn Wrapper around rotatebox

54 \cs_new:Npn \__grading_scheme_rotatebox:nnn #1 %implicit #2, #3

55 {

56 \rotatebox [ #1 ]

57 }

(End definition for\__grading_scheme_rotatebox:nnn.)

4.4 Customizable backends

We set up some functions that will be used internally, but could technically be customized at some point. For now, these are just constants.

\__grading_scheme_points:n Prints the number of points. Used in the last column of the grading scheme.

58 \cs_new:Npn \__grading_scheme_points:n #1

59 {

60 \textbf{ #1 ~ P. }

61 }

(End definition for\__grading_scheme_points:n.)

\__grading_scheme_operation:n Prints an operation. Used in the leftmost column of a block.

62 \cs_new:Npn \__grading_scheme_operation:n #1

63 {

64 { \sc #1 }

65 }

(End definition for\__grading_scheme_operation:n.)

4.5 Resources

4.5.1 Some general thoughts

This is some general reasoning about why we model data structures as we do in this package, comparing parts of LATEX3 to plainCcode.

We have to model elements, blocks and entries here. LATEX3 provides some data structures for this, and we will use property-lists to model our data structures for this package.

When thinking about what a property list is, a call to \prop_new:N essentially allocates some memory for us and makes our given argument apointerto a data structure that we refer to as a “property list”.

We want to think of these as pointers since modifying a property list at some place really also modifies this property list at another, so these behave like pointers.

Considering the grouping mechanism of TEX, this is of course not quite right for local variables (we assume that in the LATEX3 spirit, all variables are either local or global once and for all, to avoid confusion) since these rather correspond to one pointer at each grouping level, where upon entering such a grouping level, the (new) pointer is

(8)

initialized with a copy of the outer instance of the pointer and destroyed again when leaving the current grouping level.

In this spirit, we really want to think of grouping levels asscopeslike inC.

Considering functions now, a typical LATEX3 function has no return value (these would be functions with the_ppredicate or _use: functions that leave contents in the input stream), since this is in general not desired. Rather, we pass pointers as a func- tion argument and receive the desired “return value” as written into our given pointer (overwriting any prior data), which is also a common behaviour in large parts ofC.

Now, as mentioned earlier, data structures such as property queues are just pointers that refer to some tokens with specific internal structure. All functions dealing with such pointers have to ensure that these invariants remain satisfied, and this is what functions like \prop_get:NnN or \prop_put:Nn do. The key point here is that we refer to these structures only with pointers and do not deal with them directly. This is what gives us some very nice abstrict model, hiding the class invariants of a property queue from the user and providing high-level semantic access to such data structures.

Just for completeness, we mention that this is not the case for all data structures.

For example, aclisthas some structure that is well-known and can be dealt with by the user directly. That is why there are alsoclistcommands acceptiongn-type arguments for dealing with a clist, but no such commands for property-lists, as they only use N and thus essentially pointers.

If we want to model data structures now, especially ours from this package, we even want data structures containing other data structures. Although technically, storing all data of a grading scheme in a single macro would be possible, due to its recursive structure, parsing would be quite a challenge and possibly also rather slow. Also, this would requiredirect access to the representation of blocks contained in this block, which is undesired.

Compare this to the question of putting a property-list inside a property-list. Since there is no (semantic/provided) possibility of actually putting a property-list anywhere, we cannot store property-lists in property-lists directly. We can, however, store the name of a property list inside of another one, this amounts to actually storing the pointer to the first list inside the second one.

Now, back to our package, we essentially want to model blocks and alike as C-style structs that contain pointers to their elements and similar. The classic question of ownership arises in this context, so we would have to consider shallow or deep copies and a user has to watch out when dealing with our data structures.

Since only a limited set of operations is needed in our case, we take a simple approach by saying that each struct owns all its contents, that is, owns everythin its data member pointers point to, also recursively. This essentially forbids shallow-copying (violating our assumption) but we do not need this here, so this is okay.

Still, this hase some undesired consequences: Since in LATEX3 each pointer has some name, we need to construct a lot of pointers on the fly where we are not able to actually specify their names directly, so we have to indirectly deal with pointers. That means that we actually need double-pointers, i.e. local variablescontainingpointers to the data structures we are actually interested in. This is what a void**would correspond to in C. Also, note that once we store a pointer to some element in a property queue (e.g. the name of the list of members when dealing with a block), we actually also need avoid**

when retrieving this value again from the property queue, since we return by pointer.

Consequently, this leads to quite a lot of expansion-control when dealing with such pointers, and if not taking precautions, also to easy confusion about what is a pointer and what not.

(9)

Our approach to tackle these problems is described insubsection 4.6.

4.6 Pointers

This module should/will be reworked into an own package in the future. Also, there is no proper documentation for it apart from the comments in the implementation, since this is not meant to be used in other code than this package currently, nor regarded stable.

We introduce a new data type of pointer and a new argument type of P. The argument typePshall indicate a single expansionwith the assumption that this expansion will yield a single token. So, from an implementation point of view, this is the same as ano-type argument, just with further restricted assumptions.

This also enables us to generatePvariant arguments fromNvariant macros. Compare this to the usual deprecation warning that LATEX3 gives when generating an o variant from anN-type argument:

! LaTeX3 Error: Variant form ’o’ deprecated for base form ’\foo:N’. One (LaTeX3) should not change an argument from type ’N’ to type ’o’:

(LaTeX3) base form only accepts a single token argument.

Since basically anything in LATEX3 is in fact a pointer, we will introduce thepointer structure with theptrtype (suffix) and actually mean that this is avoid**.

Thus, we introduce the following conventions:

1. A TEX-pointer is a TEXcontrol sequence that represents some data.

2. Apointeris a control sequence that expands to a single TEX control sequence that is a TEX-pointer.

3. Thename of apointeris the name of the control sequence representing it. Thus, such a name always ends with_ptr by convetion.

4. Aptris said to beNULLif its expansion yields an undefined TEX control sequence.

We also refer to this as a nullptr.

5. A typed pointer is a pointer where the underlying type is specified. By this, we mean that expanding the token exactly once yields a token representing a data structure of the type we said this pointer to have or that the pointer isNULL.

6. A void pointer shall be a pointer whose actual type is unknown.

7. When aptris of typetype, we denote these by the suffix_type_ptr.

8. Dereferencing a pointer amounts to expanding it exactly once.

9. AP-type argument accepts a single token that has to be of typeptr. The token is expanded exactly once and then treated as anN-type argument in the corresponding function.

\g__ptr_counter_int Counts the number of pointers given by\ptr_new:N. This ensures that each pointer can have a unique name regardless of grouping.

66 \int_new:N \g__ptr_counter_int (End definition for\g__ptr_counter_int.)

(10)

\l__ptr_var_prefix_str Stores the prefix of new pointer variables.

67 \str_new:N \l__ptr_var_prefix_str (End definition for\l__ptr_var_prefix_str.)

\ptr_new:N \ptr_new:N⟨pointer⟩

Gives a new unique pointer that isNULL. Gives an error when the⟨pointer⟩already exists. The pointer variable is created globally.

68 \cs_new:Npn \ptr_new:N #1

69 {

70 \__ptr_get_var_prefix:NN #1 \l__ptr_var_prefix_str

71 \ptr_new:NVn #1 \l__ptr_var_prefix_str { any }

72 }

73 \cs_new:Npn \ptr_new:Nn #1 #2

74 {

75 \ptr_new:Nnn { #1 } { #2 } { any }

76 }

77 % ptr var, prefix, type

78 \cs_new:Npn \ptr_new:Nnn #1 #2 %i #3

79 {

80 \str_case:nnT

81 { #2 }

82 {

83 { l } { }

84 { g } { }

85 }

86 {

87 \tl_new:N #1

88 }

89 \__ptr_init:Nnn #1 { #2 } %i { #3 }

90 }

91 \cs_generate_variant:Nn \ptr_new:Nnn { N V n }

92 % ptr var, prefix, type

93 % assumes that the pointer name exists already in case of l or g prefix

94 \cs_new:Npn \__ptr_init:Nnn #1 #2 % implicit #3

95 {

96 \__ptr_get_var_prefix:NN #1 \l__ptr_var_prefix_str

97 \str_case:VnF

98 \l__ptr_var_prefix_str

99 {

100 { l }

101 {

102 \cs_set_eq:NN \__ptr_poly_tl_set:Nx \tl_set:Nx

103 }

104 { g }

105 {

106 \cs_set_eq:NN \__ptr_poly_tl_set:Nx \tl_gset:Nx

107 }

108 { c }

109 {

110 \cs_set_eq:NN \__ptr_poly_tl_set:Nx \tl_const:Nx

111 }

112 }

(11)

113 {

114 \str_show:N \l__ptr_var_prefix_str % TODO: show error

115 }

116 \__ptr_init_aux:Nnn #1 { #2 }

117 }

118 \cs_generate_variant:Nn \__ptr_init:Nnn { N V n }

119 % ptr var, prefix, type. assumes poly_tl_set:Nx has been set

120 \cs_new:Npn \__ptr_init_aux:Nnn #1 #2 #3

121 {

122 \__ptr_poly_tl_set:Nx #1

123 {

124 \exp_not:c

125 {

126 #2

127 __ptr__unique__

128 \int_use:N \g__ptr_counter_int

129 _

130 #3

131 }

132 }

133 \int_gincr:N \g__ptr_counter_int

134 }

135 \cs_generate_variant:Nn \__ptr_init:Nnn { N V n } (End definition for\ptr_new:N. This function is documented on page??.)

\__ptr_get_var_prefix:NN Gets the first character of the name of the variable given as #1. The first character is assumed to be one ofc,lorgby usual naming conventions.

136 \cs_new:Npn \__ptr_get_var_prefix:NN #1 #2

137 {

138 \tl_if_head_eq_charcode:fNTF { \cs_to_str:N #1 } l

139 {

140 \str_set:Nn #2 { l }

141 }

142 {

143 \tl_if_head_eq_charcode:fNTF { \cs_to_str:N #1 } g

144 {

145 \str_set:Nn #2 { g }

146 }

147 {

148 \tl_if_head_eq_charcode:fNTF { \cs_to_str:N #1 } c

149 {

150 \str_set:Nn #2 { c }

151 }

152 {

153 \msg_error:nnx { ptr } { variable-name-illegal-prefix }

154 {

155 \token_to_str:N #1

156 }

157 }

158 }

159 }

160 }

(12)

161 \msg_new:nnnn { ptr } { variable-name-illegal-prefix }

162 {

163 Requested ~ new ~ pointer ~ ’#1’ ~ has ~ illegal ~ prefix.

164 }

165 {

166 Prefix ~ should ~ be ~ one ~ of ~ ’l’, ~ ’g’ ~ or ~ ’c’.

167 }

(End definition for\__ptr_get_var_prefix:NN.)

\ptr_clear:N Clears this pointer. This makes the pointer equivalent to a newnullptr.

168 \cs_new:Npn \ptr_clear:N #1

169 {

170 \__ptr_get_var_prefix:NN #1 \l__ptr_var_prefix_str

171 \__ptr_init:NVn #1 \l__ptr_var_prefix_str { any }

172 }

173 \cs_new:Npn \ptr_clear:Nn #1 #2

174 {

175 \__ptr_init:Nnn #1 { #2 } { any }

176 }

(End definition for\ptr_clear:N. This function is documented on page??.)

\ptr_set:NN Sets the pointer to represent the given argument.

177 \cs_set_eq:NN \ptr_set:NN \tl_set:Nn

(End definition for\ptr_set:NN. This function is documented on page??.)

\ptr_set_eq:NN Accepts two pointers. The first is set to be equivalent to the second.

178 \cs_set_eq:NN \ptr_set_eq:NN \tl_set_eq:NN

(End definition for\ptr_set_eq:NN. This function is documented on page??.)

\ptr_use:N Uses the pointer, i.e. expands to the stored TEX-pointer.

179 \cs_set_eq:NN \ptr_use:N \tl_use:N

(End definition for\ptr_use:N. This function is documented on page??.)

\__ptr_check:N Checks that the given argument is a pointer.

180 \cs_new:Npn \__ptr_check:N #1

181 {

182 \tl_if_single:NF #1

183 {

184 \msg_error:nnx { ptr } { is-not-a-pointer }

185 {

186 \token_to_str:N #1

187 }

188 }

189 }

190 \msg_new:nnn { ptr } { is-not-a-pointer }

191 {

192 The ~ control ~ sequence ~ ’#1’ ~ is ~ not ~ a ~ valid ~ pointer.

193 }

(13)

(End definition for\__ptr_check:N.)

\__ptr_check:NN Checks that the second argument is a pointer.

194 \cs_new:Npn \__ptr_check:NN #1 #2

195 {

196 \__ptr_check:N #2

197 #1 #2

198 }

(End definition for\__ptr_check:NN.)

\__ptr_check:nN Checks that the second argument is a pointer.

199 \cs_new:Npn \__ptr_check:nN #1 #2

200 {

201 \__ptr_check:N #2

202 { #1 } #2

203 }

(End definition for\__ptr_check:nN.)

\l__ptr_content_tl Stores the (internal) TEX-pointer of apointer.

204 \tl_new:N \l__ptr_content_tl (End definition for\l__ptr_content_tl.)

\exp_args:NP

\exp_args:NNP

\exp_args:NNNP

\exp_args:NNNNP

\exp_args:NPP

Expands a pointer. This leaves the first tokens as a single token in the input stream, followed by the value of the pointer as a single token.

If the last argument does not expand to a single token, an error is given.

205 \cs_new:Npn \exp_args:NP #1 #2

206 {

207 \__ptr_check:N #2

208 \exp_last_unbraced:No #1 #2

209 }

210 \cs_new:Npn \exp_args:NNP #1 #2 #3

211 {

212 \__ptr_check:N #3

213 \exp_last_unbraced:NNo #1 #2 #3

214 }

215 \cs_new:Npn \exp_args:NNNP #1 #2 #3 #4

216 {

217 \__ptr_check:N #4

218 \exp_last_unbraced:NNNo #1 #2 #3 #4

219 }

220 \cs_new:Npn \exp_args:NNNNP #1 #2 #3 #4 #5

221 {

222 \__ptr_check:N #5

223 \exp_last_unbraced:NNNNo #1 #2 #3 #4 #5

224 }

225 \cs_new:Npn \exp_args:NPP #1 #2 #3

226 {

227 \__ptr_check:N #2

228 \__ptr_check:N #3

229 \exp_last_two_unbraced:Noo #1 #2 #3

230 }

(14)

(End definition for\exp_args:NP and others. These functions are documented on page??.)

\ptr_if_null:NTF Checkes if the pointer isNULL.

231 \cs_new:Npn \ptr_if_null:NT

232 {

233 \exp_args:NP \cs_if_exist:NF

234 }

235 \cs_new:Npn \ptr_if_null:NF

236 {

237 \exp_args:NP \cs_if_exist:NT

238 }

239 \cs_new:Npn \ptr_if_null:NTF #1 #2 #3

240 {

241 \exp_args:NP \cs_if_exist:NTF #1 { #3 } { #2 }

242 }

(End definition for\ptr_if_null:NTF. This function is documented on page??.)

\tl_set_eq:NP

\tl_set_eq:PN

\tl_set_eq:PP

\tl_use:P

\exp_not:P

\clist_new:P

\clist_put_right:Pn

\clist_gput_right:Pn

\clist_map_function:PN

\prop_show:P

\clist_show:P

Just variants of\tl_set_eq:NNwith indicated signature.

243 \cs_new:Npn \tl_set_eq:NP

244 {

245 \exp_args:NNP \tl_set_eq:NN

246 }

247 \cs_new:Npn \tl_set_eq:PN

248 {

249 \exp_args:NP \tl_set_eq:NN

250 }

251 \cs_new:Npn \tl_set_eq:PP

252 {

253 \exp_args:NPP \tl_set_eq:NN

254 }

255 \cs_new:Npn \tl_use:P

256 {

257 \exp_args:NP \tl_use:N

258 }

259 \cs_new:Npn \exp_not:P

260 {

261 \exp_args:NP\exp_not:N

262 }

263 \cs_new:Npn \clist_new:P

264 {

265 \exp_args:NP \clist_new:N

266 }

267 \cs_new:Npn \clist_show:P

268 {

269 \exp_args:NP \clist_show:N

270 }

271 \cs_new:Npn \clist_put_right:Pn

272 {

273 \exp_args:NP \clist_put_right:Nn

274 }

275 \cs_new:Npn \clist_gput_right:Pn

276 {

277 \exp_args:NP \clist_gput_right:Nn

(15)

278 }

279 \cs_new:Npn \clist_map_function:PN

280 {

281 \exp_args:NP \clist_map_function:NN

282 }

283 \cs_new:Npn \prop_show:P

284 {

285 \exp_args:NP \prop_show:N

286 }

(End definition for\tl_set_eq:NP and others. These functions are documented on page??.)

\ptr_show:N Shows information about this pointer, namely:

If it isNULL, then it indicates this. If it is notNULL, then the TEX-pointer and the contained contents of the TEX-pointer (in unexpanded form) are shown.

287 \cs_new:Npn \ptr_show:N #1

288 {

289 \__ptr_check:N #1

290 \ptr_if_null:NTF #1

291 {

292 \tl_show:x

293 {

294 \token_to_str:N #1 -> \exp_not:P #1 = NULL

295 }

296 }

297 {

298 \tl_show:x

299 {

300 \token_to_str:N #1 -> \exp_not:P #1 -> \exp_args:NP \exp_not:V #1

301 }

302 }

303 }

(End definition for\ptr_show:N. This function is documented on page??.)

4.7 Structs

We will model C-style structs as property-lists in this package. Each struct member is put into the property list, using its ’name’ as a key, and we store the corresponding contents there.

We will also have a local variable named correspondingly for eachstructmember.

In case we deal with a struct and want to acces its data, we load the values from the property-list into these local variables. Thus, the full information about a struct is contained in the property-list, and we can work with them quite conveniently when implementing functions.

4.8 Entries

An entry is for us the following:

struct Entry { tl description;

int points;

}

(16)

\grading_scheme_entry_new:N

\grading_scheme_entry_clear:N

\grading_scheme_entry_set_eq:NN

\grading_scheme_entry_gclear:N

\grading_scheme_entry_gset_eq:NN

Do what their signature suggests. We just forward them to the property lists.

304 \cs_set_eq:NN \grading_scheme_entry_new:N \prop_new:N

305 \cs_set_eq:NN \grading_scheme_entry_clear:N \prop_clear:N

306 \cs_set_eq:NN \grading_scheme_entry_set_eq:NN \prop_set_eq:NN

307 \cs_set_eq:NN \grading_scheme_entry_gclear:N \prop_gclear:N

308 \cs_set_eq:NN \grading_scheme_entry_gset_eq:NN \prop_gset_eq:NN

(End definition for\grading_scheme_entry_new:N and others. These functions are documented on page

??.)

\l__grading_scheme_entry_points_int

\l__grading_scheme_entry_description_tl

The mentioned local variables where we retrieve values.

309 \int_new:N \l__grading_scheme_entry_points_int

310 \tl_new:N \l__grading_scheme_entry_description_tl

(End definition for\l__grading_scheme_entry_points_intand\l__grading_scheme_entry_description_- tl.)

\grading_scheme_entry_set_description:Nn

\grading_scheme_entry_gset_description:Nn

Sets the description.

311 \cs_new:Npn \grading_scheme_entry_set_description:Nn #1 % implicit description

312 {

313 \prop_put:Nnn #1 { description }

314 }

315 \cs_new:Npn \grading_scheme_entry_gset_description:Nn #1 % implicit description

316 {

317 \prop_gput:Nnn #1 { description }

318 }

(End definition for \grading_scheme_entry_set_description:Nn and \grading_scheme_entry_gset_- description:Nn. These functions are documented on page??.)

\grading_scheme_entry_set_points:Nn

\grading_scheme_entry_gset_points:Nn

Sets the points.

319 \cs_new:Npn \grading_scheme_entry_set_points:Nn #1 #2

320 {

321 \prop_put:Nnx #1 { points } { \int_eval:n { #2 } }

322 }

323 \cs_new:Npn \grading_scheme_entry_gset_points:Nn #1 #2

324 {

325 \prop_gput:Nnn #1 { points } { \int_eval:n { #2 } }

326 }

(End definition for\grading_scheme_entry_set_points:Nnand\grading_scheme_entry_gset_points:Nn.

These functions are documented on page??.)

\grading_scheme_entry_get_description:NN Gets the description of the entry and stores it in#2. The assignment is local.

327 \cs_new:Npn \grading_scheme_entry_get_description:NN #1 %implicit #2

328 {

329 \prop_get:NnN #1 { description }

330 }

(End definition for\grading_scheme_entry_get_description:NN. This function is documented on page

??.)

(17)

\grading_scheme_entry_get_points:NN Gets the points of the entry and stores it in#2. The assignment is local.

331 \cs_new:Npn \grading_scheme_entry_get_points:NN #1 %implicit #2

332 {

333 \prop_get:NnN #1 { points }

334 }

(End definition for\grading_scheme_entry_get_points:NN. This function is documented on page??.)

\__grading_scheme_entry_load_points:N Loads the points into the local variable

335 \cs_new:Npn \__grading_scheme_entry_load_points:N #1

336 {

337 \grading_scheme_entry_get_points:NN #1 \l__grading_scheme_entry_points_int

338 }

(End definition for\__grading_scheme_entry_load_points:N.)

\__grading_scheme_entry_load_description:N Loads the description of an entry

339 \cs_new:Npn \__grading_scheme_entry_load_description:N #1

340 {

341 \grading_scheme_entry_get_description:NN #1 \l__grading_scheme_entry_description_tl

342 }

(End definition for\__grading_scheme_entry_load_description:N.)

\grading_scheme_entry_format:NnnN

\grading_scheme_entry_gformat:NnnN

\grading_scheme_entry_format:PnnN

\grading_scheme_entry_gformat:PnnN

\grading_scheme_entry_put:NnnN{⟨entry⟩}{⟨indent⟩}{⟨width⟩}{⟨tl var⟩}

Puts the formatted contents of the entry into the⟨tl var⟩. The⟨indent⟩specify how many tabs will be inserted before adding the contents. The ⟨width⟩specifies how many columns this entry will occupy. This⟨width⟩has to be at least 2.

An\\is inserted at the end of the entry.

343 \cs_new:Npn \grading_scheme_entry_format:NnnN

344 {

345 \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_put_right:Nx

346 \__grading_scheme_entry_format:NnnN

347 }

348 \cs_new:Npn \grading_scheme_entry_gformat:NnnN

349 {

350 \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_gput_right:Nx

351 \__grading_scheme_entry_format:NnnN

352 }

353 \cs_new:Npn \grading_scheme_entry_format:PnnN

354 {

355 \exp_args:NP \grading_scheme_entry_format:NnnN

356 }

357 \cs_new:Npn \grading_scheme_entry_gformat:PnnN

358 {

359 \exp_args:NP \grading_scheme_entry_gformat:NnnN

360 }

(End definition for\grading_scheme_entry_format:NnnN and others. These functions are documented on page??.)

(18)

\__grading_scheme_entry_format:NnnN

\__grading_scheme_entry_format:PnnN

Aux function that assumes that \__grading_scheme_tl_put_right:Nxhas been so to globally or locally putting into the token list.

361 \cs_new:Npn \__grading_scheme_entry_format:NnnN #1 #2 #3 #4

362 {

363 ⟨∗log⟩

364 \__grading_scheme_log:x

365 { Formatting ~ entry ~ ’\token_to_str:N #1’ ~ into ~ ’\token_to_str:N #4’ with }

366 \__grading_scheme_log:n { indent = ’#2’ ~ and ~ width ~ ’#3’ }

367 \prop_log:N #1

368 \__grading_scheme_log_incr:

369 ⟨/log⟩

370 \__grading_scheme_entry_assert_description:N #1 % implicitly loads value

371 \__grading_scheme_entry_assert_points:N #1 % implicitly loads value

372 \__grading_scheme_tl_put_right:Nx #4

373 {

374 \prg_replicate:nn { #2 } { & }

375 \exp_not:N \__grading_scheme_multicolumn:nnn

376 {

377 \int_eval:n { #3 -1 }

378 }

379 { l }

380 {

381 \exp_not:V \l__grading_scheme_entry_description_tl

382 }

383 &

384 \exp_not:N \__grading_scheme_points:n

385 {

386 \tl_use:N \l__grading_scheme_entry_points_int

387 }

388 \\

389 }

390 ⟨∗log⟩

391 \__grading_scheme_log_decr:

392 \__grading_scheme_log:x { / Formatting ~ entry ~ ’\token_to_str:N #1’ }

393 ⟨/log⟩

394 }

395 \cs_new:Npn \__grading_scheme_entry_forrmat:PnnN % implicit #1-4

396 {

397 \exp_args:NP \__grading_scheme_entry_format:NnnN

398 }

(End definition for\__grading_scheme_entry_format:NnnNand\__grading_scheme_entry_format:PnnN.)

\__grading_scheme_entry_assert_description:N

\__grading_scheme_entry_assert_points:N

These functions check the presence of values of an entry. If an entry is absent, an error message is omitted.

399 \cs_new:Npn \__grading_scheme_entry_assert_description:N #1

400 {

401 \__grading_scheme_entry_load_description:N #1

402 \quark_if_no_value:NT \l__grading_scheme_entry_description_tl

403 {

404 \msg_error:nnxxx { grading-scheme } { missing-value }

405 { entry } { \token_to_str:N #1 } { description }

406 }

407 }

(19)

408 \cs_new:Npn \__grading_scheme_entry_assert_points:N #1

409 {

410 \__grading_scheme_entry_load_points:N #1

411 \quark_if_no_value:NT \l__grading_scheme_entry_points_int

412 {

413 \msg_error:nnxxx { grading-scheme } { missing-value }

414 { entry } { \token_to_str:N #1 } { points }

415 }

416 }

417 \msg_new:nnn { grading-scheme } { missing-value }

418 {

419 #1 ~ ’#2’ ~ has ~ no ~ #3.

420 }

(End definition for\__grading_scheme_entry_assert_description:N and \__grading_scheme_entry_- assert_points:N.)

4.9 Blocks

4.9.1 Struct setting / reading

A⟨block⟩is for us the following:

struct Block { clist* elements;

tl text;

tl operation;

}

\grading_scheme_block_new:N

\grading_scheme_block_clear:N

\grading_scheme_block_set_eq:NN

\grading_scheme_block_gclear:N

\grading_scheme_block_gset_eq:NN

Do what thear names suggest. We just forward these to the property lists.

421 \cs_set_eq:NN \grading_scheme_block_new:N \prop_new:N

422 \cs_set_eq:NN \grading_scheme_block_clear:N \prop_clear:N

423 \cs_set_eq:NN \grading_scheme_block_set_eq:NN \prop_gset_eq:NN

424 \cs_set_eq:NN \grading_scheme_block_gclear:N \prop_gclear:N

425 \cs_set_eq:NN \grading_scheme_block_gset_eq:NN \prop_gset_eq:NN

(End definition for\grading_scheme_block_new:N and others. These functions are documented on page

??.)

\l__grading_scheme_block_elements_clist_ptr

\l__grading_scheme_block_description_tl

\l__grading_scheme_block_operation_tl

The mentioned local variables where we retrieve values.

426 \ptr_new:N \l__grading_scheme_block_elements_clist_ptr

427 \tl_new:N \l__grading_scheme_block_description_tl

428 \tl_new:N \l__grading_scheme_block_operation_tl

(End definition for\l__grading_scheme_block_elements_clist_ptr,\l__grading_scheme_block_description_- tl, and\l__grading_scheme_block_operation_tl.)

\grading_scheme_block_set_description:Nn

\grading_scheme_block_gset_description:Nn

\grading_scheme_block_set_operation_tl:Nn

\grading_scheme_block_gset_operation_tl:Nn

\grading_scheme_block_set_elements:NN

\grading_scheme_block_gset_elements:NN

\grading_scheme_block_set_elements:NP

\grading_scheme_block_gset_elements:NP

Set the description / operation or elements of the block.

When setting elements, a⟨clist var⟩is expected.

429 \cs_new:Npn \grading_scheme_block_set_description:Nn #1 % implicit description

430 {

431 \prop_put:Nnn #1 { description }

432 }

433 \cs_new:Npn \grading_scheme_block_gset_description:Nn #1 % implicit description

(20)

434 {

435 \prop_gput:Nnn #1 { description }

436 }

437 \cs_new:Npn \grading_scheme_block_set_operation:Nn #1 % implicit operation

438 {

439 \prop_put:Nnn #1 { operation }

440 }

441 \cs_new:Npn \grading_scheme_block_gset_operation:Nn #1 % implicit operation

442 {

443 \prop_gput:Nnn #1 { operation }

444 }

445 \cs_new:Npn \grading_scheme_block_set_elements:NN #1 % implicit elements clist

446 {

447 \prop_put:Nnn #1 { elements }

448 }

449 \cs_new:Npn \grading_scheme_block_gset_elements:NN #1 % implicit elements clist

450 {

451 \prop_gput:Nnn #1 { elements }

452 }

453 \cs_new:Npn \grading_scheme_block_set_elements:NP

454 {

455 \exp_args:NNP \grading_scheme_block_set_elements:NN

456 }

457 \cs_new:Npn \grading_scheme_block_gset_elements:NP

458 {

459 \exp_args:NNP \grading_scheme_block_gset_elements:NN

460 }

(End definition for\grading_scheme_block_set_description:Nn and others. These functions are doc- umented on page??.)

\grading_scheme_block_get_description:NN

\grading_scheme_block_get_operation:NN

\grading_scheme_block_get_elements:NN

\grading_scheme_block_get_description:NN⟨block var⟩⟨tl var⟩

\grading_scheme_block_get_operation:NN⟨block var⟩⟨tl var⟩

\grading_scheme_block_get_elements:NN⟨block var⟩⟨clist ptr⟩

Get access to the members of the block. The assignment is local. The returned values might be\q_no_valueif no value is present.

461 \cs_new:Npn \grading_scheme_block_get_description:NN #1 % implicit #2

462 {

463 \prop_get:NnN #1 { description }

464 }

465 \cs_new:Npn \grading_scheme_block_get_operation:NN #1 % implicit #2

466 {

467 \prop_get:NnN #1 { operation }

468 }

469 \cs_new:Npn \grading_scheme_block_get_elements:NN #1 % implicit #2

470 {

471 \prop_get:NnN #1 { elements }

472 }

(End definition for\grading_scheme_block_get_description:NN,\grading_scheme_block_get_operation:NN, and\grading_scheme_block_get_elements:NN. These functions are documented on page??.)

\__grading_scheme_block_load_description:N

\__grading_scheme_block_load_operation:N

\__grading_scheme_block_load_elements:NN

Loads the members into the corresponding local variables.

473 \cs_new:Npn \__grading_scheme_block_load_description:N #1

(21)

474 {

475 \grading_scheme_block_get_description:NN #1 \l__grading_scheme_block_description_tl

476 }

477 \cs_new:Npn \__grading_scheme_block_load_operation:N #1

478 {

479 \grading_scheme_block_get_operation:NN #1 \l__grading_scheme_block_operation_tl

480 }

481 \cs_new:Npn \__grading_scheme_block_load_elements:N #1

482 {

483 \grading_scheme_block_get_elements:NN #1 \l__grading_scheme_block_elements_clist_ptr

484 }

(End definition for\__grading_scheme_block_load_description:N,\__grading_scheme_block_load_- operation:N, and\__grading_scheme_block_load_elements:NN.)

\__grading_scheme_block_ensure_elements:N Ensures that this block has an elements attribute that is a valid clist pointer.

If no value is present, or the pointer isNULL, a pointer and/or the clist variable are created.

485 \cs_new:Npn \__grading_scheme_block_ensure_elements:N % implicit #1

486 {

487 \cs_set_eq:NN

488 \__grading_scheme_block_set_elements_optg:NP

489 \grading_scheme_block_set_elements:NP

490 \__grading_scheme_block_ensure_elements_aux:nN { l }

491 }

492 \cs_new:Npn \__grading_scheme_block_gensure_elements:N % implicit #1

493 {

494 \cs_set_eq:NN

495 \__grading_scheme_block_set_elements_optg:NP

496 \grading_scheme_block_gset_elements:NP

497 \__grading_scheme_block_ensure_elements_aux:nN { g } %i #1

498 }

499 % prefix, block

500 % assumes that \__grading_scheme_block_set_elements_optg:NP has been

501 \cs_new:Npn \__grading_scheme_block_ensure_elements_aux:nN #1 #2

502 {

503 \__grading_scheme_block_load_elements:N #2

504 \quark_if_no_value:NT \l__grading_scheme_block_elements_clist_ptr

505 {

506 \ptr_clear:Nn \l__grading_scheme_block_elements_clist_ptr { #1 }

507 \__grading_scheme_block_set_elements_optg:NP

508 #2

509 \l__grading_scheme_block_elements_clist_ptr

510 }

511 \ptr_if_null:NT \l__grading_scheme_block_elements_clist_ptr

512 {

513 \clist_new:P \l__grading_scheme_block_elements_clist_ptr

514 }

515 }

(End definition for\__grading_scheme_block_ensure_elements:N.)

\grading_scheme_block_add_element:NN

\grading_scheme_block_gadd_element:NN

\grading_scheme_block_add_element:PP

\grading_scheme_block_gadd_element:PP

\grading_scheme_block_add_element:NN⟨block var⟩⟨element var⟩

Add an element to the block.

(22)

516 \cs_new:Npn \grading_scheme_block_add_element:NN #1 % implicit element

517 {

518 \__grading_scheme_block_ensure_elements:N #1 % also loads local variable

519 \clist_put_right:Pn \l__grading_scheme_block_elements_clist_ptr

520 }

521 \cs_new:Npn \grading_scheme_block_gadd_element:NN #1 % implicit element

522 {

523 \__grading_scheme_block_gensure_elements:N #1 % also loads local variable

524 \clist_gput_right:Pn \l__grading_scheme_block_elements_clist_ptr

525 }

526 \cs_new:Npn \grading_scheme_block_add_element:PP

527 {

528 \exp_args:NPP \grading_scheme_block_add_element:NN

529 }

530 \cs_new:Npn \grading_scheme_block_gadd_element:PP

531 {

532 \exp_args:NPP \grading_scheme_block_gadd_element:NN

533 }

534 \cs_new:Npn \grading_scheme_block_add_element:PN

535 {

536 \exp_args:NP \grading_scheme_block_add_element:NN

537 }

538 \cs_new:Npn \grading_scheme_block_gadd_element:PN

539 {

540 \exp_args:NP \grading_scheme_block_gadd_element:NN

541 }

(End definition for \grading_scheme_block_add_element:NN and others. These functions are docu- mented on page??.)

4.9.2 Formatting blocks

\grading_scheme_block_format:NnnnN

\grading_scheme_block_gformat:NnnnN

\grading_scheme_block_format:PnnnN

\grading_scheme_block_gformat:PnnnN

\grading_scheme_block_format:NnnnN⟨block var⟩{⟨indent⟩}{⟨width⟩}{⟨indent first row⟩}⟨tl var⟩

Formats this block and puts the control sequence into⟨tl var⟩.

The⟨indent⟩and⟨width⟩work as in \grading_scheme_entry_format:NnnN.

⟨indent first row⟩ can be any ⟨boolean expression⟩and indicates if the first row is also indented. Set this to false to start the block in a row of the tabular that already has contents.

542 \cs_new:Npn \grading_scheme_block_format:NnnnN %implicit #1-5

543 {

544 \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_put_right:Nx

545 \cs_set_eq:NN \__grading_scheme_element_format_optg:NnnnN \grading_scheme_element_format:NnnnN

546 \cs_set_eq:NN \__grading_scheme_tl_set:Nn \tl_set:Nn

547 \__grading_scheme_block_format:NnnnN

548 }

549 \cs_new:Npn \grading_scheme_block_gformat:NnnnN %implicit #1-5

550 {

551 \cs_set_eq:NN \__grading_scheme_tl_put_right:Nx \tl_gput_right:Nx

552 \cs_set_eq:NN \__grading_scheme_element_format_optg:NnnnN \grading_scheme_element_gformat:NnnnN

553 \cs_set_eq:NN \__grading_scheme_tl_set:Nn \tl_gset:Nn

554 \__grading_scheme_block_format:NnnnN

555 }

556 \cs_new:Npn \grading_scheme_block_format:PnnnN % implicit #1-5

(23)

557 {

558 \exp_args:NP

559 \grading_scheme_block_format:NnnnN

560 }

561 \cs_new:Npn \grading_scheme_block_gformat:PnnnN % implicit #1-5

562 {

563 \exp_args:NP

564 \grading_scheme_block_gformat:NnnnN

565 }

(End definition for\grading_scheme_block_format:NnnnN and others. These functions are documented on page??.)

For formatting the block, we need some local variables:

\l__grading_scheme_block_indent_bool Controls whether the \__grading_scheme_block_indent:nN macro will actually per- form an indent.

566 \bool_new:N \l__grading_scheme_block_indent_bool (End definition for\l__grading_scheme_block_indent_bool.)

\__grading_scheme_block_height_int Locally stores the height of the block to be typeset.

567 \int_new:N \l__grading_scheme_block_height_int (End definition for\__grading_scheme_block_height_int.)

\__grading_scheme_block_format:NnnnN

\__grading_scheme_block_format:PnnnN

Aux function. Assumes that\__grading_scheme__tl_put_right:Nxhas been set prop- erly.

568 \cs_new:Npn \__grading_scheme_block_format:NnnnN #1 #2 #3 #4 #5

569 {

570 ⟨∗log⟩

571 \__grading_scheme_log:x

572 {

573 Formatting ~ block ~ ’\token_to_str:N #1’ ~ into ~ ’\token_to_str:N #5’

574 ~ with ~ indent =’#2’, ~ width ~ ’#3’ ~ and ~ first ~

575 row = ’\bool_to_str:n { #4 }’

576 }

577 \prop_log:N #1

578 \__grading_scheme_block_load_elements:N #1

579 \exp_args:NP \clist_log:N \l__grading_scheme_block_elements_clist_ptr

580 \__grading_scheme_log_incr:

581 ⟨/log⟩

We need grouping here so that our indentation boolean is not messed up by recursive calls:

582 \bool_set:Nn \l__grading_scheme_block_indent_bool { #4 && \c_true_bool }

583 \group_begin:

584 \__grading_scheme_block_load_description:N #1

585 \grading_scheme_block_get_height:NN #1 \l__grading_scheme_block_height_int We now format the description of the block if a value is present.

586 \quark_if_no_value:NF \l__grading_scheme_block_description_tl

587 {

588 \__grading_scheme_block_indent:nN { #2 } #5

589 \__grading_scheme_tl_put_right:Nx #5

590 {

(24)

591 \exp_not:N \__grading_scheme_multicolumn:nnn

592 {

593 \int_eval:n { #3 }

594 }

595 { l| }

596 {

597 \exp_not:V \l__grading_scheme_block_description_tl

598 }

599 \\

600 \exp_not:N \__grading_scheme_cline:nn

601 {

602 \int_eval:n { #2 + 2 }

603 }

604 {

605 \int_eval:n { #2 + #3 }

606 }

607 }

608 }

Now, we have to format the operation of this block. This is a multirow with rotated description

609 \__grading_scheme_block_indent:nN { #2 } #5

610 \__grading_scheme_block_assert_operation:N #1

611 \__grading_scheme_tl_put_right:Nx #5

612 {

613 \exp_not:N \__grading_scheme_multirow:nnn

614 {

615 \int_eval:n { \int_use:N \l__grading_scheme_block_height_int - 1 }

616 }

617 { * }

618 {

619 \exp_not:N \__grading_scheme_rotatebox:nnn

620 { origin = c }

621 { 90 }

622 {

623 \exp_not:N \__grading_scheme_operation:n

624 {

625 \exp_not:V \l__grading_scheme_block_operation_tl

626 }

627 }

628 }

629 &

630 }

The first element of our block must not be indented:

631 \bool_set_false:N \l__grading_scheme_block_indent_bool

Now, we want to recursively typeset all elements of this block. We need a customized function for this to map over the elements.

632 \cs_set:Npn \__grading_scheme_block_format_element:N ##1

633 {

634 \__grading_scheme_element_format_optg:NnnnN

635 ##1

636 { #2 + 1 } % indent is one more that the current block

637 { #3 - 1 } % width is one less than current block

(25)

638 { \l__grading_scheme_block_indent_bool }

639 #5

This ensures that the second and all further elements will get indented:

640 \bool_set_true:N \l__grading_scheme_block_indent_bool

641 }

642 \__grading_scheme_block_ensure_elements:N #1 % load + sanitize elements

643 \clist_map_function:PN

644 \l__grading_scheme_block_elements_clist_ptr

645 \__grading_scheme_block_format_element:N

Now, we need to ’smuggle out’ the output token list of the current group.

646 \exp_args:NNNV

647 \group_end:

648 \__grading_scheme_tl_set:Nn

649 #5

650 #5

651 ⟨∗log⟩

652 \__grading_scheme_log_decr:

653 \__grading_scheme_log:x { / Formatting ~ block ~ ’\token_to_str:N #1’ }

654 ⟨/log⟩

655 }

656 \cs_new:Npn \__grading_scheme_block_format:PnnnN

657 {

658 \exp_args:NP \__grading_scheme_block_format:NnnnN

659 }

(End definition for\__grading_scheme_block_format:NnnnNand\__grading_scheme_block_format:PnnnN.)

\__grading_scheme_block_assert_operation:N Asserts that the block has an operation and loads it. If no operation is set, an error is emitted.

660 \cs_new:Npn \__grading_scheme_block_assert_operation:N #1

661 {

662 \__grading_scheme_block_load_operation:N #1

663 \quark_if_no_value:NT \l__grading_scheme_block_operation_tl

664 {

665 \msg_error:nnxxx { grading-scheme } { missing-value}

666 { block }

667 { \token_to_str:N #1 }

668 { operation }

669 }

670 }

(End definition for\__grading_scheme_block_assert_operation:N.)

\__grading_scheme_block_indent:nN \__grading_scheme_block_indent:nN{⟨indent⟩}⟨tl var⟩

Performs the indent into ⟨tl var⟩ iff \l__grading_scheme_block_indent_bool is true.

Sets\l__grading_scheme_block_indent_boolto true afterwards.

671 \cs_new:Npn \__grading_scheme_block_indent:nN #1 #2

672 {

673 \bool_if:NT \l__grading_scheme_block_indent_bool

674 {

675 \__grading_scheme_tl_put_right:Nx #2

(26)

676 {

677 \prg_replicate:nn { #1 } { & }

678 }

679 }

680 \bool_set_true:N \l__grading_scheme_block_indent_bool

681 }

(End definition for\__grading_scheme_block_indent:nN.)

4.9.3 Width and height of a block

\l__grading_scheme_height_sum_int

\l__grading_scheme_height_acc_int

Some temporary int values

682 \int_new:N \l__grading_scheme_height_sum_int

683 \int_new:N \l__grading_scheme_height_acc_int

(End definition for\l__grading_scheme_height_sum_int and\l__grading_scheme_height_acc_int.)

\grading_scheme_block_get_height:NN

\grading_scheme_block_get_height:PN

\grading_scheme_block_get_height:NN⟨block var⟩⟨int var⟩ Gets the height of a block and stores it into the⟨int var⟩.

684 \cs_new:Npn \grading_scheme_block_get_height:NN #1 #2

685 {

686 ⟨∗log⟩

687 \__grading_scheme_log:x { Getting ~ height ~ of ~ block ~ ’\token_to_str:N #1’ }

688 \__grading_scheme_log_incr:

689 ⟨/log⟩

Grouping is needed to not mess up local variables in the recursion:

690 \group_begin:

691 \__grading_scheme_block_load_elements:N #1

692 \int_zero:N \l__grading_scheme_height_sum_int

693 \clist_map_function:PN

694 \l__grading_scheme_block_elements_clist_ptr

695 \__grading_scheme_block_height_accumulator:N

696 \grading_scheme_block_if_description:NT #1

697 {

698 \int_incr:N \l__grading_scheme_height_sum_int

699 }

Smuggle out this length at return it to the caller:

700 \exp_args:NNNV

701 \group_end:

702 \int_set:Nn #2 \l__grading_scheme_height_sum_int

703 ⟨∗log⟩

704 \__grading_scheme_log_decr:

705 \__grading_scheme_log:x

706 {

707 / Getting ~ height ~ of ~ block ~ ’\token_to_str:N #1’:

708 ’\int_use:N #2’

709 }

710 ⟨/log⟩

711 }

712 \cs_new:Npn \grading_scheme_block_get_height:PN

713 {

714 \exp_args:NP \grading_scheme_block_get_height:NN

715 }

(27)

(End definition for\grading_scheme_block_get_height:NNand\grading_scheme_block_get_height:PN.

These functions are documented on page??.)

\__grading_scheme_block_height_accumulator:N This is mapped on the elements of a block and accumulates the heights.

716 \cs_new:Npn \__grading_scheme_block_height_accumulator:N #1

717 {

718 \grading_scheme_element_get_height:NN #1 \l__grading_scheme_height_acc_int

719 \int_add:Nn \l__grading_scheme_height_sum_int

720 { \int_use:N \l__grading_scheme_height_acc_int }

721 }

(End definition for\__grading_scheme_block_height_accumulator:N.)

\grading_scheme_block_if_description:NTF Tests if the given⟨block var⟩has a description set or not. Also loads this description

722 \cs_new:Npn \grading_scheme_block_if_description:NT #1 % implicit #2

723 {

724 \__grading_scheme_block_load_description:N #1

725 \quark_if_no_value:NF \l__grading_scheme_block_description_tl

726 }

727 \cs_new:Npn \grading_scheme_block_if_description:NF #1 % implicit #2

728 {

729 \__grading_scheme_block_load_description:N #1

730 \quark_if_no_value:NT \l__grading_scheme_block_description_tl

731 }

732 \cs_new:Npn \grading_scheme_block_if_description:NTF #1 #2 #3

733 {

734 \__grading_scheme_block_load_description:N #1

735 \quark_if_no_value:NTF \l__grading_scheme_block_description_tl

736 { #3 }

737 { #2 }

738 }

(End definition for\grading_scheme_block_if_description:NTF. This function is documented on page

??.)

\l__grading_scheme_max_width_int

(End definition for\l__grading_scheme_max_width_int.)

\l__grading_scheme_width_acc_int

\l__grading_scheme_max_width_int

Some temporary int values

739 \int_new:N \l__grading_scheme_max_width_int

740 \int_new:N \l__grading_scheme_width_acc_int

(End definition for\l__grading_scheme_width_acc_int and\l__grading_scheme_max_width_int.)

\grading_scheme_block_get_natural_width:NN

\grading_scheme_block_get_natural_width:PN

Gets the “natural” width of a block, that is: The minimal width of this block so that it can be typeset properly.

741 \cs_new:Npn \grading_scheme_block_get_natural_width:NN #1 #2

742 {

743 ⟨∗log⟩

744 \__grading_scheme_log:x

745 { Getting ~ natural ~ width ~ of ~ block ~ ’\token_to_str:N #1’. }

746 \__grading_scheme_log_incr:

747 ⟨/log⟩

References

Related documents

Figure 2: A view, dated 21 February 1850, from the east side of the Patent Copper Company’s first smelting house (foreground), the SAMA’s smelting house-become-store beyond it,

We apply the new notion in Subsection 2.2 where we prove that every Banach space that has a strongly computable Schauder basis (to be defined) has a computable

Note that when we issue an instruction to test σ on x , we need to make sure that we did not previously test on x any string comparable with σ.... Is A computable from a c.e.,

A509 adac open space bicycle fitting N 1 point CROSS CONTINUOUS Centre of Bicycle Fitting (ADAC) OpenSpace BicycleFitting. A634 adac open space general fixture N 1 point

We apply the new no- tion in Subsection 2.2 where we prove that every Banach space that has a strongly computable Schauder basis (to be defined) has a computable

If this closure occurs as proposed, this would mean that upgrades at Ludmilla WWTP are incomplete before 3 ML/day of additional effluent is diverted from Larrakeyah (about 30%

The evolution equa- tions for the six quantities contained in these tensors are reduced in number in two cases: (i) for arbitrary surfaces, we use principal coordinates to obtain

• Do you feel there was enough support I help from your Rural professionals, i.e Bank Manager, Lawyer, Accountant, Farm Advisor.. • Were you able to fmd support

If it is important that the students in our schools are taught by committed Christian teachers then there is a need to expand our collective efforts to put before Christians

 Uses a Python list data structure to store the items in the queue.  There are three

e Introduction and this chapter along with the Summary or Abstract are the most important parts of the thesis.. ⁸No man is an Island, entire of itself; every man is a piece of

ID Terms of reference requirements EIS section number 2.2 Provide a detailed and comprehensive assessment of potential impacts on and risks to marine environmental quality

That is, the value on the right-hand side of an assignment statement is of the same type as the variable on the left-hand side (the types must be COMPATIBLE ).. Displaying the Value

Another general concept is “large prime variation” which, in a nutshell, is to also store “nearly smooth” relations (i.e., elements that are the product of a smooth element with

Thus we would expect the distance between the Black and Borda rules to increase as the frequency of that a Condorcet winners exist increases, and increase with Borda’s

Characterization of Metarhizium anisopliae isolates from Tasmanian pasture soils and their pathogenicity to the red-headed pasture cockchafer (Coleoptera: Scarabaeidea:

In this paper we prove a variant of the Kochen-Specker theorem showing that, under the same assumption of noncontextuality, if a single one-dimensional projection observable is

public void valueChanged(TreeSelectionEvent e) { //Returns the last path element of the selection //Returns the last path element of the selection. //This method is useful only when

A number of important emigration effects works through the domestic labour market. They are less apparent than monetary flows, some difficult to quantify and others

This report provides information on the activities, achievements and performance of the Office of the Commonwealth Ombudsman (the Office) for the 2016–17 financial year..

Virtually all published research has been around financial and production effects, with only passing reference to supposed personal benefits, and very little has been done or

If there is a category of group standards available for the intended use of your product (for example, Leather and Textile Products Group Standards), the next step is to classify

existence. In making such an estimate, the Government Printer was requested to take as understood that each author body would have its report printed by the