summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/longdivision
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/longdivision
Initial commit
Diffstat (limited to 'macros/latex/contrib/longdivision')
-rw-r--r--macros/latex/contrib/longdivision/README.md53
-rw-r--r--macros/latex/contrib/longdivision/longdivision.sty765
-rw-r--r--macros/latex/contrib/longdivision/longdivision_manual.pdfbin0 -> 135922 bytes
-rw-r--r--macros/latex/contrib/longdivision/longdivision_manual.tex166
4 files changed, 984 insertions, 0 deletions
diff --git a/macros/latex/contrib/longdivision/README.md b/macros/latex/contrib/longdivision/README.md
new file mode 100644
index 0000000000..e459c12ca8
--- /dev/null
+++ b/macros/latex/contrib/longdivision/README.md
@@ -0,0 +1,53 @@
+longdivision v1.1.0
+========================
+Author: Hood Chatham
+Email: hood@mit.edu
+Date: 2019-03-24
+Description:
+License: All files have the Latex Project Public License.
+Files:
+ longdivision.sty
+ longdivision_manual.tex
+ longdivision_manual.pdf
+ README.md
+
+
+Does the long division algorithm and typesets the results. The dividend must
+be a positive decimal number and the divisor must be a positive integer.
+Correctly handles repeating decimals, putting a bar over the repeated part of
+the decimal. Handles dividends up to 20 digits long gracefully (though the
+typeset result will take up about a page) and dividends between 20 and 60
+digits long slightly less gracefully.
+
+Defines macros \longdivision and \intlongdivision. Each takes two arguments,
+a dividend and divisor. \longdivision keeps dividing until the remainder is
+zero, or it encounters a repeated remainder. \longdivision stops when the
+dividend stops (though the dividend doesn't have to be an integer).
+
+\intlongdivision behaves similarly to the \longdiv command defined in
+longdiv.tex, though I think \intlongdivision looks better, and it can handle
+much larger dividends and divisors (the dividend is only constrained by the
+size of the page, and the divisor can be up to 8 digits long).
+
+See the package manual for more information.
+
+Email me at hood@mit.edu to submit bug reports, request new features, etc.
+The current development copy is hosted at https://github.com/hoodmane/longdivision.
+
+
+Changelog:
+==========
+
+## [1.1.0] (2018-10-08)
+### Fixed:
+- If the "\longdivision" command is in math mode, the numbers are typeset in math mode too (reported by Yu-Tsiang Tai).
+- The "\longdivision" command now can handle macros as arguments (as suggested by Mike Jenck).
+
+### Added:
+- Multiple typesetting styles
+- Multiple styles for indicating a repeating decimal
+- Typesetting partial long division (as suggested by Cameron McLeman).
+
+
+## [1.0.0] (2017-02-05)
+
diff --git a/macros/latex/contrib/longdivision/longdivision.sty b/macros/latex/contrib/longdivision/longdivision.sty
new file mode 100644
index 0000000000..98349704fe
--- /dev/null
+++ b/macros/latex/contrib/longdivision/longdivision.sty
@@ -0,0 +1,765 @@
+%% Package: longdivision.sty version 1.0
+%% Author: Hood Chatham
+%% Email: hood@mit.edu
+%% Date: 2/5/2017
+%% License: Latex Project Public License
+
+
+\ProvidesPackage{longdivision}
+\RequirePackage{xparse}
+
+\ExplSyntaxOn
+
+
+% Core registers
+\bool_new:N \l__longdiv_mathmode_bool
+\bool_new:N \l_longdiv_repeating_decimal_bool
+\bool_new:N \l__longdiv_added_point_bool
+\bool_new:N \l__longdiv_seen_point_bool
+\bool_new:N \l__longdiv_seen_digit_bool
+\bool_new:N \l__longdiv_stopped_early_stage_bool
+\int_new:N \l__longdiv_quotient_int
+\int_new:N \l__longdiv_position_int
+\int_new:N \l__longdiv_point_digit_int
+\int_new:N \l__longdiv_repeat_digit_int
+
+\dim_new:N \g__longdiv_temp_dim % For measuring the distance to the right side of digits
+
+% These are used to make sure division doesn't run off the page.
+\int_new:N \l__longdiv_extra_digits_int
+\int_new:N \l__longdiv_max_extra_digits_int
+\int_set:Nn \l__longdiv_max_extra_digits_int { 100 } % Infinite (just needs to be greater than max_total_digits_int and max_display_divisions_int)
+\int_new:N \l__longdiv_digits_requested_int
+\int_set:Nn \l__longdiv_digits_requested_int { 100 } % Infinite (just needs to be greater than max_total_digits_int and max_display_divisions_int)
+
+\int_const:Nn \c__longdiv_max_total_digits_int { 60 }
+\int_const:Nn \c__longdiv_max_display_divisions_int { 20 }
+\int_new:N \l__longdiv_display_divisions_int
+
+% Key-value arguments
+\cs_new:Npn \longdivisionkeys #1 { \keys_set:nn { longdivision } { #1 } }
+
+\keys_define:nn { longdivision }
+{
+ stage .int_set:N = \l__longdiv_digits_requested_int,
+ max~extra~digits .int_set:N = \l__longdiv_max_extra_digits_int,
+ unknown .code:n = {
+ %\def\temp{#1}\show\temp
+ \int_set:Nn \l__longdiv_max_extra_digits_int { \l_keys_key_tl }
+ }
+}
+
+\cs_new:Nn \longdiv_register_repeating_decimal_style_choices:n {
+ \keys_define:nn { longdivision } {
+ repeating~decimal~style .choices:nn =
+ { #1 }
+ {
+ \cs_set_eq:Nc \longdiv_linkedlist_indicate_repeating_decimal:n { longdiv_linkedlist_indicate_repeating_decimal_##1:n }
+ }
+ }
+}
+
+\cs_new:Nn \longdiv_register_style_choices:n {
+ \keys_define:nn { longdivision } {
+ style .choices:nn =
+ { #1 }
+ {
+ \cs_set_eq:Nc \longdiv_typeset_main: { longdiv_typeset_main_##1: }
+ }
+ }
+}
+
+\longdiv_register_style_choices:n { default, standard, tikz, german }
+\longdiv_register_repeating_decimal_style_choices:n { overline, dots, dots~all, parentheses, none }
+
+\cs_new:Nn \longdiv_define_style:nn {
+ \cs_new:cpn { longdiv_typeset_main_ #1 :} { #2 }
+ \longdiv_register_style_choices:n { #1 }
+}
+\let \longdivdefinestyle \longdiv_define_style:nn
+
+%%
+%% The linked list
+%%
+
+% This token list just stores a reference to the first entry in the linked list
+\tl_new:N \l__longdiv_linkedlist_tl
+\tl_set:Nn\l__longdiv_linkedlist_tl { \longdiv_linkedlist_next:n { 0 } }
+\int_new:N \l__longdiv_linkedlist_length_int
+
+% Set the next entry to be a no-op so that when expanded the last "null pointer" just disappears
+\cs_new:Nn \longdiv_linkedlist_set_next_do_nothing: {
+ \cs_set_eq:cN { longdiv_linkedlist ~ \int_use:N \l__longdiv_linkedlist_length_int } \prg_do_nothing:
+}
+\longdiv_linkedlist_set_next_do_nothing:
+
+% "pointer" to next element (argument is the element's id)
+\cs_new:Nn \longdiv_linkedlist_next:n { \use:c { longdiv_linkedlist ~ #1 } }
+
+\cs_new:Nn \longdiv_linkedlist_add:n {
+ \cs_set:cpx { longdiv_linkedlist ~ \int_use:N \l__longdiv_linkedlist_length_int}{
+ \exp_not:n{ \longdiv_linkedlist_element:n { #1 } } \exp_not:N \longdiv_linkedlist_next:n { \int_eval:n { \l__longdiv_linkedlist_length_int + 1} }
+ }
+ \int_incr:N \l__longdiv_linkedlist_length_int
+ \longdiv_linkedlist_set_next_do_nothing:
+}
+\cs_new_eq:NN \longdiv_linkedlist_element:n \use:n
+\cs_generate_variant:Nn \longdiv_linkedlist_add:n { f }
+
+% The easy implementation of remove_tail and the \longdiv_linkedlist_indicate_repeating_decimal commands is why I chose the "linked list" format.
+% Delete last element of list.
+\cs_new:Nn \longdiv_linkedlist_remove_tail: {
+ \int_decr:N \l__longdiv_linkedlist_length_int
+ \longdiv_linkedlist_set_next_do_nothing:
+}
+
+%%
+%% Entry points
+%%
+
+% \tl_rescan to ignore spaces in input.
+\NewDocumentCommand \longdivision { omm } {
+ \group_begin:
+ \IfNoValueF { #1 } {
+ \keys_set:nn { longdivision } { #1 }
+ }
+ \tl_rescan:nn { \ExplSyntaxOn } { \longdiv_start:xx { #2 } { #3 } }
+ \group_end:
+}
+
+% Same as \longdiv[0]{#1}{#2}.
+\NewDocumentCommand \intlongdivision { omm } {
+ \group_begin:
+ \IfNoValueF { #1 } {
+ \keys_set:nn { longdivision } { #1 }
+ }
+ \int_set:Nn \l__longdiv_max_extra_digits_int { 0 }
+ \tl_rescan:nn { \ExplSyntaxOn } { \longdiv_start:xx { #2 } { #3 } }
+ \group_end:
+}
+
+% Check input is valid then enter main loop.
+% We use \int_eval:w to ensure that the dividend has no unnecessary leading zeroes and doesn't begin with a decimal point.
+% Note that \int_eval:n wouldn't work here because it inserts a "\relax" token that would not get eaten by \numexpr if
+% #1 contains a decimal point. This "\relax" causes trouble for the division main loop.
+\cs_new:Nn \longdiv_start:nn {
+ \longdiv_check_dividend:n { #1 }
+ \longdiv_check_divisor:n { #2 }
+ % Second copy of #1 is eaten by \longdiv_typeset:nnn to print the dividend
+ \exp_args:Nnnff \longdiv_get_new_digit:nnn { } { #2 } { \int_eval:w 0#1 } { \int_eval:w 0#1 }
+ \longdiv_break_point: { #1 } { #2 }
+}
+\cs_generate_variant:Nn \longdiv_start:nn { xx }
+
+\cs_new_eq:NN \longdiv_break_point: \use_none:nn
+
+%%
+%% Input checkers
+%%
+
+% Parse through the dividend token by token
+% Check that every token is a digit with the exception of at most one .
+\cs_new:Nn \longdiv_check_dividend:n {
+ \longdiv_check_dividend_before_point:N #1 \q_stop
+}
+
+\cs_new:Nn \longdiv_check_dividend_before_point:N {
+ \token_if_eq_meaning:NNF #1 \q_stop {
+ \token_if_eq_meaning:NNTF #1 . {
+ \longdiv_check_dividend_seen_point:N
+ }{
+ \longdiv_check_dividend_isdigit:N #1
+ \longdiv_check_dividend_before_point:N
+ }
+ }
+}
+
+\cs_new:Nn \longdiv_check_dividend_seen_point:N {
+ \token_if_eq_meaning:NNF #1 \q_stop {
+ \longdiv_check_dividend_isdigit:N #1
+ \longdiv_check_dividend_seen_point:N
+ }
+}
+
+\cs_new:Nn \longdiv_check_dividend_isdigit:N {
+ \bool_if:nF { \token_if_eq_meaning_p:NN #1 0
+ || \token_if_eq_meaning_p:NN #1 1 || \token_if_eq_meaning_p:NN #1 2 || \token_if_eq_meaning_p:NN #1 3
+ || \token_if_eq_meaning_p:NN #1 4 || \token_if_eq_meaning_p:NN #1 5 || \token_if_eq_meaning_p:NN #1 6
+ || \token_if_eq_meaning_p:NN #1 7 || \token_if_eq_meaning_p:NN #1 8 || \token_if_eq_meaning_p:NN #1 9
+ }{
+ \longdiv_error:nwnn { dividend_invalid }
+ }
+}
+
+% Check that there is no ., that it is at most 8 digits, and that the entire argument can get assigned to a count variable
+% There's no way to do this last check in expl3, so I use plaintex \newcount, \afterassignment, and \l__longdiv_temp_int =.
+\newcount \l__longdiv_temp_int
+\cs_new:Nn \longdiv_check_divisor:n {
+ \tl_if_in:nnT { #1 } { . } {
+ \longdiv_error:nwnn { divisor_not_int }
+ }
+ % We have to do the length check before the "validity" check because the "validity" check makes an assignment
+ % which throws a low level error if the number to be assigned is too large.
+ \int_compare:nNnF { \tl_count:n { #1 } } < \c_nine {
+ \longdiv_error:nwnn { divisor_too_large }
+ }
+ % Idea here: if #1 is a valid number, \l__longdiv_temp_int = 0#1 will absorb all of it.
+ % So if there's any left, throw an error. Leading zero ensures that it fails on -1 and
+ % that if #1 starts with some other nondigit character that it won't cause
+ % "Missing number, treated as zero."
+ \afterassignment \longdiv_check_divisor_aux:w
+ \l__longdiv_temp_int = 0 #1 \scan_stop:
+}
+
+\cs_new:Npn \longdiv_check_divisor_aux:w #1 \scan_stop: {
+ \tl_if_empty:nF { #1 } {
+ \longdiv_error:nwnn { divisor_invalid }
+ }
+ \int_compare:nNnT \l__longdiv_temp_int = \c_zero {
+ \longdiv_error:nwnn { divisor_zero }
+ }
+}
+
+% Absorb up to break_point to gracefully quit out of the macro
+\cs_new:Npn \longdiv_error:nwnn #1 #2 \longdiv_break_point: {
+ \msg_error:nnnn { longdivision } { #1 }
+}
+
+% Errors:
+\msg_new:nnn { longdivision } { dividend_invalid } { Dividend ~ '#1' ~ is ~ invalid ~ (\msg_line_context:).}
+\msg_new:nnn { longdivision } { divisor_too_large }
+ { Divisor ~ '#2' ~ is ~ too ~ large ~ (\msg_line_context:). ~ It ~ has ~ \tl_count:n { #2 } ~ digits, ~ but ~ divisors ~ can ~ be ~ at ~ most ~ 9 ~ digits ~ long. }
+\msg_new:nnn { longdivision } { divisor_not_int } { Divisor ~ '#2' ~ is ~ not ~ an ~ integer ~ (\msg_line_context:). }
+\msg_new:nnn { longdivision } { divisor_invalid } { Divisor ~ '#2' ~ is ~ invalid ~ (\msg_line_context:). }
+
+% Warnings:
+\msg_new:nnn { longdivision } { work_stopped_early } { The ~ work ~ display ~ stopped ~ early ~ to ~ avoid ~ running ~ off ~ the ~ page ~ (\msg_line_context:). }
+\msg_new:nnn { longdivision } { division_stopped_early } { The ~ division ~ stopped ~ early ~ to ~ avoid ~ running ~ off ~ the ~ page ~ (\msg_line_context:).}
+\msg_new:nnn { longdivision } { no_division_occurred }
+ { Either ~ the ~ dividend ~ was ~ zero ~ or ~ you ~ used ~ \token_to_str:N \intlongdiv \space and ~ the ~ dividend ~ was ~less ~ than ~ the ~ divisor. ~
+ This ~ isn't ~ a ~ big ~ deal, ~ but ~ the ~ result ~ probably ~ looks ~ silly. }
+\msg_new:nnn { longdivision } { no_tikz } { You ~ requested ~ "style~=~tikz" ~ but ~ tikz ~ has ~ not ~ been ~ loaded. ~ Falling ~ back ~ to ~ "style~=~standard". }
+
+
+%%
+%% Division
+%%
+
+% #1 -- remainder
+% #2 -- divisor
+% #3 -- rest of digits of dividend
+\cs_new:Nn \longdiv_get_new_digit:nnn {
+ \tl_if_empty:nTF { #3 } { % Are we out of digits?
+ % If we haven't hit the decimal point add it to the quotient and dividend
+ % Set seen_digit false so that we can remove the decimal point later if it divided evenly or we used \intlongdiv
+ \bool_if:NF \l__longdiv_seen_point_bool {
+ \longdiv_add_point: %
+ \bool_set_false:N \l__longdiv_seen_digit_bool
+ \bool_set_true:N \l__longdiv_added_point_bool
+ }
+ \longdiv_divide_no_more_digits:nn { #1 } { #2 }
+ }{
+ \longdiv_get_new_digit_aux:nnw { #1 } { #2 } #3;
+ }
+}
+\cs_generate_variant:Nn \longdiv_get_new_digit:nnn {xnn}
+
+\cs_new:Npn \longdiv_get_new_digit_aux:nnw #1 #2 #3 #4;{
+ \token_if_eq_meaning:NNTF #3 . {
+ \longdiv_add_point:
+ \bool_set_true:N \l__longdiv_seen_digit_bool % Prevent this decimal point from being removed later
+ \bool_set_false:N \l__longdiv_added_point_bool
+ \longdiv_get_new_digit:nnn { #1 } { #2 } { #4 }
+ }{
+ \longdiv_divide:nn { #1 #3 } { #2 } { #4 }
+ }
+}
+
+% Adds a decimal point, with a leading 0 if necessary, and records the current position in \l__longdiv_point_digit_int
+\cs_new:Nn \longdiv_add_point: {
+ \bool_set_true:N \l__longdiv_seen_point_bool
+ \bool_if:NTF \l__longdiv_seen_digit_bool {
+ \longdiv_linkedlist_add:n { . }
+ }{
+ \longdiv_linkedlist_add:n { 0. } % Add a leading zero
+
+ }
+ \int_set_eq:NN \l__longdiv_point_digit_int \l__longdiv_position_int % Record the position of the point
+}
+
+% Divide when we still have more digits.
+% #1 -- thing to divide
+% #2 -- divisor
+% Finds the quotient, adds it to the linked list and to the work token list then recurses.
+\cs_new:Nn \longdiv_divide:nn {
+ \int_compare:nNnTF \l__longdiv_position_int = \l__longdiv_digits_requested_int {
+ \longdiv_divide_end_early:nnn { #1 } { #2 }
+ }{
+ \int_set:Nn \l__longdiv_quotient_int { \int_div_truncate:nn { #1 } { #2 } }
+ \bool_if:nTF {
+ \int_compare_p:nNn \l__longdiv_quotient_int = \c_zero % If the quotient was zero, we might not have to print it
+ && !\l__longdiv_seen_digit_bool % If no other digits have been printed
+ && !\l__longdiv_seen_point_bool % And we are before the decimal point
+ }{
+ \int_incr:N \l__longdiv_digits_requested_int % Get an extra digit, this one doesn't count.
+ }{ % Otherwise print it and record that we've seen a digit (all further 0's must be printed)
+ \bool_set_true:N \l__longdiv_seen_digit_bool
+ \longdiv_linkedlist_add:f { \int_use:N \l__longdiv_quotient_int }
+ }
+ \int_incr:N \l__longdiv_position_int
+ \longdiv_divide_record:nn{ #1 }{ #2 }
+ \longdiv_get_new_digit:xnn { \longdiv_remainder:nn { #1 } { #2 } } { #2 }
+ }
+}
+
+\cs_generate_variant:Nn \tl_reverse:n {f}
+
+% Called if we stop early due to \l__longdiv_digits_requested_int.
+% #1 -- thing to divide
+% #2 -- divisor
+% #3 -- rest of digits of dividend
+% If we stop early, we have to pad the quotient with the extra length of the dividend
+% because the top bar of the division symbol uses the length of the quotient to determine
+% the length of the bar, but we need it to always be at least as long as the dividend.
+% Also, we need to delete the extra digit that has been carried down
+\cs_new:Nn \longdiv_divide_end_early:nnn {
+ % For some reason we need to shift the typeset work over by half a digit if we quit early due to "stage" option
+ % so we need to set a flag so that the work typesetter can know to do this.
+ \bool_set_true:N \l__longdiv_stopped_early_stage_bool
+ % \int_set:Nn \l_tmpa_int { \use:c { longdiv_linkedlist ~ \int_eval:n { \l__longdiv_linkedlist_length_int - 1 } } }
+ \longdiv_linkedlist_add:n { \phantom { #3 0 } }
+ \exp_args:Nx \longdiv_typeset:nnn { \longdiv_delete_last:n { #1 } } { #2 }
+}
+
+% Deletes the last digit of number.
+\cs_new:Nn \longdiv_delete_last:n { \tl_reverse:f { \tl_tail:f { \tl_reverse:f { #1 } } } }
+
+% Divide when we are out of digits.
+% #1 -- remainder from last time (we will add a zero to the end)
+% #2 -- divisor
+% This case is more complicated because we have to check for repeated remainders, and whether to stop
+% though we are certainly after the decimal point so we don't need to check whether we need to print 0's.
+\cs_new:Nn \longdiv_divide_no_more_digits:nn {
+ % If we've seen this remainder before, we're done. Use the appropriate command
+ % to insert the overline, and then typeset everything
+ \cs_if_exist_use:cTF { longdiv_remainders ~ \int_eval:n { #1 } }{ % \int_eval:n to remove leading zero
+ \longdiv_typeset:nnn { #1 } { #2 }
+ }{
+ \bool_if:nTF {
+ \int_compare_p:nNn \l__longdiv_extra_digits_int = \l__longdiv_max_extra_digits_int
+ ||\int_compare_p:nNn \l__longdiv_position_int = \c__longdiv_max_total_digits_int
+ ||\int_compare_p:nNn \l__longdiv_position_int = \l__longdiv_digits_requested_int
+ }{
+ \int_compare:nNnT \l__longdiv_position_int = \c__longdiv_max_total_digits_int {
+ \msg_warning:nn { longdivision } { division_stopped_early }
+ }
+ \longdiv_typeset:nnn { #1 } { #2 }
+ }{
+ % Otherwise, record that we've seen this remainder and the position we're in
+ % In case this is the first digit of the repeated part
+ \cs_set:cpx { longdiv_remainders ~ \int_eval:n { #1 } }{ % \int_eval:n to remove leading zero
+ \int_set:Nn \l__longdiv_repeat_digit_int { \int_use:N \l__longdiv_linkedlist_length_int }
+ \exp_not:N \longdiv_linkedlist_indicate_repeating_decimal:n { \int_use:N \l__longdiv_linkedlist_length_int }
+ }
+ % Now we have to use #1 0 everywhere
+ \int_set:Nn \l__longdiv_quotient_int { \int_div_truncate:nn { #1 0 } { #2 } }
+ \longdiv_linkedlist_add:f { \int_use:N \l__longdiv_quotient_int }
+ \bool_set_true:N \l__longdiv_seen_digit_bool % We've seen a digit after the decimal point, don't need to remove it
+ \int_incr:N \l__longdiv_position_int
+ \int_incr:N \l__longdiv_extra_digits_int
+ \longdiv_divide_record:nn { #1 0 } { #2 }
+ \longdiv_divide_no_more_digits:xn { \longdiv_remainder:nn { #1 0 } { #2 } } { #2 }
+ }
+ }
+}
+\cs_generate_variant:Nn \longdiv_divide_no_more_digits:nn { xn }
+
+% Whenever we see the remainder 0, we're done, and we don't have to put an overline.
+\cs_new:cpn { longdiv_remainders ~ 0 }{}
+
+% This command checks if the quotient was zero, and if so preserves the leading zero by avoiding \int_eval:n
+% This is so that e.g, \longdiv{14.1}{7} doesn't screw up
+\cs_new:Nn \longdiv_remainder:nn {
+ \int_compare:nNnTF \l__longdiv_quotient_int = \c_zero
+ { #1 }
+ { \int_eval:n { #1 - \l__longdiv_quotient_int * #2 } }
+}
+
+
+% We're going to store the "work" for the long division in this tl as a series of triples:
+% #1 -- number of digits we've processed so far (for positioning subtractions and determining if point should be added)
+% #2 -- old remainder (thing to subtract from)
+% #3 -- quotient * divisor (thing to subtract)
+\tl_new:N \l__longdiv_work_tl
+\cs_new:Nn \longdiv_divide_record:nn {
+ \int_compare:nNnTF \l__longdiv_display_divisions_int < \c__longdiv_max_display_divisions_int {
+ \int_compare:nNnF \l__longdiv_quotient_int = \c_zero { % If the quotient was zero, nothing needs to be typeset
+ \tl_set:Nx \l__longdiv_work_tl {
+ \l__longdiv_work_tl
+ { \int_use:N \l__longdiv_position_int } { #1 } { \int_eval:n { \l__longdiv_quotient_int * #2 } }
+ }
+ \int_incr:N \l__longdiv_display_divisions_int
+ }
+ }{
+ \int_compare:nNnT \l__longdiv_display_divisions_int = \c__longdiv_max_display_divisions_int {
+ \int_compare:nNnF \l__longdiv_quotient_int = \c_zero {
+ \tl_set:Nx \l__longdiv_work_tl {
+ \l__longdiv_work_tl
+ { \int_use:N \l__longdiv_position_int } { #1 } { \int_eval:n { \l__longdiv_quotient_int * #2 } }
+ \exp_not:N \longdiv_typeset_work_last:nn { \int_use:N \l__longdiv_position_int } { \int_eval:n { #1 - \l__longdiv_quotient_int * #2 } }
+ }
+ \int_incr:N \l__longdiv_display_divisions_int
+ \msg_warning:nn { longdivision } { work_stopped_early }
+ }
+ }
+ }
+}
+
+%%
+%% Typesetting
+%%
+
+
+%% Indicate repeating decimals
+% These are all different implementations of \longdiv_linkedlist_indicate_repeating_decimal:n
+% They take one input which is the index of the start of the repeating decimal in the linked list
+
+% Chosen using "repeating decimal style", default is "dots all"
+% possible values: "overline", "dots", "dots all", "parentheses"
+
+% Put an \overline over the repeated digits. \overline only works in math mode, so we have to use \ensuremath. Then we put an \hbox
+% to take ourselves
+\cs_new:Nn \longdiv_linkedlist_indicate_repeating_decimal_overline:n {
+ \cs_set:cpx { longdiv_linkedlist ~ #1 }{
+ \ensuremath{ \overline { \bool_if:NF \l__longdiv_mathmode_bool \hbox { \exp_not:f { \use:c { longdiv_linkedlist ~ #1 } } } } }
+ }
+}
+
+\cs_new:cn { longdiv_linkedlist_indicate_repeating_decimal_dots~all:n } {
+ \cs_set:cpx { longdiv_linkedlist ~ #1 }{
+ \exp_not:n {
+ \cs_set:Npn \longdiv_linkedlist_element:n ##1 { \dot ##1 }
+ }
+ \ensuremath { \noexpand \dot \exp_not:f { \use:c { longdiv_linkedlist ~ #1 } } }
+ }
+}
+
+\cs_new:Nn \longdiv_linkedlist_indicate_repeating_decimal_dots:n {
+ \cs_set:cpx { longdiv_linkedlist ~ \int_eval:n { \l__longdiv_linkedlist_length_int - 1 } }{
+ \noexpand\dot \use:c { longdiv_linkedlist ~ \int_eval:n { \l__longdiv_linkedlist_length_int - 1 } }
+ }
+ \cs_set:cpx { longdiv_linkedlist ~ #1 }{
+ \ensuremath { \noexpand \dot \exp_not:f { \use:c { longdiv_linkedlist ~ #1 } } }
+ }
+}
+
+\bool_new:N \l__longdiv_repeating_decimal_parentheses_bool
+\cs_new:Nn \longdiv_linkedlist_indicate_repeating_decimal_parentheses:n {
+ \cs_set:cpx { longdiv_linkedlist ~ #1 }{
+ ( \exp_not:f { \use:c { longdiv_linkedlist ~ #1 } } )
+ }
+ % Don't insert extra space for parenthesis in german typesetting because the quotient isn't directly above dividend and work.
+ \cs_if_eq:NNF \longdiv_typeset_main: \longdiv_typeset_main_german:{
+ \bool_set_true:N \l__longdiv_repeating_decimal_parentheses_bool
+ \cs_set:Nn \longdiv_typeset_extra_zeroes: {
+ \bool_if:NT \l__longdiv_added_point_bool { . }
+ \prg_replicate:nn { #1 - \l__longdiv_linkedlist_length_int + \l__longdiv_extra_digits_int } { 0 } \hphantom (
+ \prg_replicate:nn { \l__longdiv_position_int - #1 } { 0 } \hphantom{ ) }
+ }
+ }
+}
+
+% Do nothing, don't indicate repeating digits at all.
+\cs_new:Nn \longdiv_linkedlist_indicate_repeating_decimal_none:n {
+
+}
+
+\cs_new_eq:NN \longdiv_linkedlist_indicate_repeating_decimal:n \longdiv_linkedlist_indicate_repeating_decimal_overline:n
+
+
+% \l__longdiv_linkedlist_tl -- quotient
+% #1 -- remainder
+% #2 -- divisor
+% #3 -- dividend
+\cs_new:Nn \longdiv_typeset:nnn {
+ \mode_if_math:TF { \bool_set_true:N \l__longdiv_mathmode_bool } { \bool_set_false:N \l__longdiv_mathmode_bool }
+ \cs_set:Npn \longdiv_typeset_dividend: {
+ \longdiv_typeset_number:n {
+ #3
+ \bool_if:NT \l__longdiv_seen_digit_bool { % we don't want to add a trailing decimal point to the dividend if it divided evenly
+ \longdiv_typeset_extra_zeroes:
+ }
+ }
+ }
+ \cs_set:Npn \longdiv_typeset_work: { \longdiv_typeset_work:n { #1 } }
+ \cs_set:Npn \longdiv_typeset_divisor: { \longdiv_typeset_number:n { #2 } }
+ \cs_set:Npn \longdiv_typeset_remainder: { \longdiv_typeset_number:n { #1 } } % This isn't used in current typesetting code, just could be nice to have
+ \bool_set:Nn \l_longdiv_repeating_decimal_bool { \int_compare_p:nNn \l__longdiv_repeat_digit_int > 0 } % This isn't used in current typesetting code, just could be nice to have
+ \let\longdivdividend\longdiv_typeset_dividend:
+ \let\longdivdivisor\longdiv_typeset_divisor:
+ \let\longdivquotient\longdiv_typeset_quotient:
+ \let\longdivwork\longdiv_typeset_work:
+ \bool_if:NF \l__longdiv_seen_digit_bool { \longdiv_linkedlist_remove_tail: } % If we haven't seen any new digits since adding a terminal decimal point, delete it.
+ \longdiv_typeset_main:
+}
+
+
+\cs_new:Nn \longdiv_typeset_extra_zeroes: {
+ \bool_if:NT \l__longdiv_added_point_bool { . }
+ \prg_replicate:nn { \l__longdiv_extra_digits_int } { 0 }
+}
+
+\cs_new:Nn \longdiv_typeset_main_default: {
+ \bool_if:NTF \l__longdiv_is_tikz_loaded_bool {
+ \longdiv_typeset_main_tikz:
+ } {
+ \longdiv_typeset_main_standard:
+ }
+}
+\cs_new_eq:NN \longdiv_typeset_main: \longdiv_typeset_main_default:
+
+
+\longdiv_define_style:nn { standard } {
+ \hskip4pt
+ \rule{0pt}{22pt} \longdiv_typeset_divisor: \, \begin{tabular}[b]{@{}r@{}}
+ \longdiv_typeset_quotient:\,
+ \\\hline
+
+ \smash{\big)}\begin{tabular}[t]{@{}l@{}}
+ \longdiv_typeset_dividend: \\
+ \longdiv_typeset_work:\\[3pt]
+ \end{tabular}\,
+ \end{tabular}
+ \hskip5.3pt
+}
+
+\bool_new:N \l__longdiv_is_tikz_loaded_bool
+\AtBeginDocument{ \@ifpackageloaded { tikz }{ \bool_gset_true:N \l__longdiv_is_tikz_loaded_bool } { } }
+
+\longdiv_define_style:nn { german } {
+ \begin{tabular}[t]{@{}l@{}}
+ \longdiv_typeset_dividend: \hskip1pt : \hskip1pt \longdiv_typeset_divisor: \hskip4pt = \hskip4pt \longdiv_typeset_quotient: \\
+ \longdiv_typeset_work:
+ \end{tabular}
+}
+
+
+\newlength{\longdiv@dividendlength}
+\newlength{\longdiv@dividendheight}
+\newlength{\longdiv@divisorheight}
+\newlength{\longdiv@maxheight}
+
+\let\longdiv@ifl@aded\@ifl@aded
+\let\longdiv@pkgextension\@pkgextension
+\def\longdiv@ifpackageloaded{\@ifl@aded\@pkgextension}
+
+\longdiv_define_style:nn { tikz }{
+ \let\@ifl@aded\longdiv@ifl@aded
+ \let\@pkgextension \longdiv@pkgextension
+ \bool_if:NTF \l__longdiv_is_tikz_loaded_bool {
+ \longdiv@typeset@tikz@rest
+ } {
+ \msg_warning:nn { longdivision } { no_tikz }
+ \longdiv_typeset_main_standard:
+ }
+}
+
+
+\def\longdiv@typeset@tikz@rest{
+ \let\longdiv@typeset@dividend\longdiv_typeset_dividend:
+ \let\longdiv@typeset@divisor\longdiv_typeset_divisor:
+ \let\longdiv@typeset@quotient\longdiv_typeset_quotient:
+ \let\longdiv@typeset@work\longdiv_typeset_work:
+ \settowidth{\longdiv@dividendlength}{1.\longdiv_typeset_dividend:}
+ \settoheight{\longdiv@dividendheight}{\longdiv_typeset_dividend:}
+ \settoheight{\longdiv@maxheight}{\longdiv_typeset_dividend:\longdiv_typeset_divisor:}
+ \settoheight{\longdiv@divisorheight}{\longdiv_typeset_divisor:}
+ \l__longdiv_rulethickness_dim = 0.2mm
+ \longdiv@typeset@main@tikz@helper
+}
+
+\ExplSyntaxOff
+\def\longdiv@typeset@main@tikz@helper{
+ \begin{tikzpicture} [baseline=.5pt]
+ \draw (1pt,.5*\longdiv@divisorheight) node [left] {\longdiv@typeset@divisor};
+ \draw (\longdiv@dividendlength,.5*\longdiv@dividendheight) node [left] {\longdiv@typeset@dividend};
+ \draw [line width=0.2mm] (0pt,-.22*\longdiv@dividendheight) arc (-70:60:\longdiv@maxheight*.41 and \longdiv@maxheight*.88) -- ++(\longdiv@dividendlength-2pt,0pt);
+ \draw (\longdiv@dividendlength,\longdiv@divisorheight+\longdiv@maxheight*.3) node[above left] {
+ \longdiv@typeset@quotient
+ };
+ \draw (0,0) node[below right] {
+ \begin{tabular}[t]{@{}l@{}}
+ \longdiv@typeset@work
+ \end{tabular}
+ };
+ \end{tikzpicture}
+}
+\ExplSyntaxOn
+
+
+\cs_new:Nn \longdiv_typeset_quotient: {
+ \int_compare:nNnTF \l__longdiv_linkedlist_length_int = \c_zero
+ {
+ \bool_if:NTF \l__longdiv_stopped_early_stage_bool
+ { }
+ { \longdiv_typeset_number:n { 0 } }
+ }
+ { \longdiv_typeset_number:n { \l__longdiv_linkedlist_tl } }
+}
+
+
+\cs_new:Nn \longdiv_typeset_number:n {
+ \bool_if:NTF \l__longdiv_mathmode_bool { \ensuremath{#1} } { #1 }
+}
+
+
+% Iterate through the division "work" and typeset it
+\cs_new:Nn \longdiv_typeset_work:n {
+ \tl_if_empty:NTF \l__longdiv_work_tl {
+ \msg_warning:nn { longdivision } { no_division_occurred }
+ }{
+ \exp_after:wN \longdiv_typeset_work_first:nnn \l__longdiv_work_tl
+ \int_compare:nNnT \l__longdiv_display_divisions_int < \c__longdiv_max_display_divisions_int {
+ \exp_args:No \longdiv_typeset_work_last:nn { \int_use:N \l__longdiv_position_int } { #1 }
+ }
+ }
+}
+
+% #1 -- digits in to the right side of the numbers we are writing
+% #2 -- remainder from last time with new digits added to the right
+% #3 -- quotient * divisor
+% _first only typesets quotient * divisor and the line
+% _rest typesets result from last time, quotient * divisor and the line
+% _last only typesets the remainder from last time
+\cs_new:Nn \longdiv_typeset_work_first:nnn {
+ \longdiv_typeset_setwidth:n { #1 }
+ \hspace{\g__longdiv_temp_dim}
+ \llap { \longdiv_insert_point_ifneeded:nn { #1 } { #3 } }
+ \\\longdiv_rule:nn{#1}{#3}
+ \peek_meaning:NT \bgroup {
+ \longdiv_typeset_work_rest:nnn
+ }
+}
+
+\cs_new:Nn \longdiv_typeset_work_rest:nnn {
+ \longdiv_typeset_setwidth:n { #1 }
+ \hspace{\g__longdiv_temp_dim}
+ \llap { \longdiv_insert_point_ifneeded:nn { #1 } { #2 } }
+ \\
+ \hspace{\g__longdiv_temp_dim}
+ \llap { \longdiv_insert_point_ifneeded:nn { #1 } { #3 } }
+ \\\longdiv_rule:nn{#1}{#3}
+ \peek_meaning:NT \bgroup {
+ \longdiv_typeset_work_rest:nnn
+ }
+}
+
+% #1 -- digits in to the right side of the numbers we are writing
+% #2 -- remainder from last time with new digits added to the right
+\cs_new:Nn \longdiv_typeset_work_last:nn {
+ \longdiv_typeset_setwidth:n { #1 }
+ \hspace{\g__longdiv_temp_dim}
+ \llap { \longdiv_insert_point_ifneeded:nn { #1 } { #2 } }
+}
+
+% #1 -- the start position of the substring
+% #2 -- the substring
+% #3 -- the position we are checking for
+\prg_new_conditional:Nnn \longdiv_if_contains_position:nnn { TF,T,F } {
+ \bool_if:nTF {
+ \int_compare_p:nNn { #1 } > #3
+ && \int_compare_p:nNn { #1 - \tl_count:n { #2 } } < #3
+ }{
+ \prg_return_true:
+ }{
+ \prg_return_false:
+ }
+}
+
+% Set \g__longdiv_temp_dim equal to digitwidth * number of digits
+% If we are past the decimal point, add \c__longdiv_pointwidth_dim
+\cs_new:Nn \longdiv_typeset_setwidth:n {
+ \dim_gset:Nn \g__longdiv_temp_dim { #1\c__longdiv_digitwidth_dim }
+ % For some reason we need to shift everything over by half a digit if we quit early due to "stage" option
+ \bool_if:NT \l__longdiv_stopped_early_stage_bool { \dim_gadd:Nn \g__longdiv_temp_dim { -0.5\c__longdiv_digitwidth_dim } }
+ \int_compare:nNnT \l__longdiv_point_digit_int < { #1 } {
+ \dim_gadd:Nn \g__longdiv_temp_dim \c__longdiv_pointwidth_dim
+ }
+ \bool_if:NT \l__longdiv_repeating_decimal_parentheses_bool {
+ \int_compare:nNnT \l__longdiv_repeat_digit_int < { #1 } {
+ \dim_gadd:Nn \g__longdiv_temp_dim \c__longdiv_parenwidth_dim
+ }
+ }
+}
+
+% If the number ends after the decimal point ( #1 > \l__longdiv_point_digit_int )
+% and start before it ( #1 - length(#2) < \l__longdiv_point_digit_int) insert a
+% decimal point in the appropriate position of #2. Otherwise just return #2
+\cs_new:Nn \longdiv_insert_point_ifneeded:nn {
+ \tl_set:Nn \l_tmpa_tl { #2 }
+ \bool_if:NT \l__longdiv_repeating_decimal_parentheses_bool {
+ \longdiv_if_contains_position:nnnT { #1 } { #2 } { \l__longdiv_repeat_digit_int } {
+ \tl_set:Nx \l_tmpa_tl {
+ \exp_not:N \longdiv_insert:nff { \hskip \c__longdiv_parenwidth_dim } %)
+ { \int_eval:n{\l__longdiv_repeat_digit_int - #1 + \tl_count:n { #2 }} }
+ { \tl_use:N \l_tmpa_tl }
+ }
+ }
+ }
+ \longdiv_if_contains_position:nnnT { #1 } { #2 } { \l__longdiv_point_digit_int } {
+ \tl_set:Nx \l_tmpa_tl { \longdiv_insert:nff . {\int_eval:n{\l__longdiv_point_digit_int - #1 + \tl_count:n { #2 }}} { \tl_use:N \l_tmpa_tl } }
+ }
+ \longdiv_typeset_number:n { \tl_use:N \l_tmpa_tl }
+}
+
+% Walk #2 digits across #3 and then insert #1
+\cs_new:Nn \longdiv_insert:nnn {
+ \longdiv_insert_aux:onN { #2 } { #1 } #3
+}
+\cs_generate_variant:Nn \longdiv_insert:nnn { nff }
+
+\cs_new:Nn \longdiv_insert_aux:nnN {
+ \int_compare:nNnTF { #1 } = \c_zero {
+ #2#3
+ }{
+ #3 \longdiv_insert_aux:onN { \int_eval:n { #1 - 1 } } { #2 }
+ }
+}
+\cs_generate_variant:Nn \longdiv_insert_aux:nnN {onN}
+
+
+% Okay, this is another section where we are adulterated with plaintex stuff.
+% It would be easy to reimplement \settowidth, but \hrule and \noalign have no
+% expl3 name anyways. Since I only use these dim variables with \settowidth, I declare
+% them with \newdimen rather than \dim_new:N
+\newdimen \c__longdiv_digitwidth_dim
+\settowidth \c__longdiv_digitwidth_dim { 0 }
+\newdimen \c__longdiv_pointwidth_dim
+\settowidth \c__longdiv_pointwidth_dim { . }
+\newdimen \c__longdiv_parenwidth_dim
+\settowidth \c__longdiv_parenwidth_dim { ( }
+\newdimen \l__longdiv_tempwidth_dim
+\newdimen \l__longdiv_rulethickness_dim
+\l__longdiv_rulethickness_dim = 0.2mm
+
+\cs_new:Nn \longdiv_rule:nn {
+ \noalign {
+ \settowidth \l__longdiv_tempwidth_dim { #2 }
+ % Check whether the decimal point occurred in the middle of the current number
+ % because if so, it's longer by pointwidth.
+ \longdiv_if_contains_position:nnnT { #1 } { #2 } { \l__longdiv_point_digit_int } {
+ \dim_add:Nn \l__longdiv_tempwidth_dim \c__longdiv_pointwidth_dim
+ }
+ % If we use parens to denote the repeating part of the quotient, they take up space too. Test if a paren occurs.
+ \bool_if:NT \l__longdiv_repeating_decimal_parentheses_bool {
+ \longdiv_if_contains_position:nnnT { #1 } { #2 } { \l__longdiv_point_digit_int } {
+ \dim_add:Nn \l__longdiv_tempwidth_dim \c__longdiv_parenwidth_dim
+ }
+ }
+ \box_move_right:nn { \g__longdiv_temp_dim - \l__longdiv_tempwidth_dim } {
+ \vbox:n { \hrule width \l__longdiv_tempwidth_dim height \l__longdiv_rulethickness_dim }
+ }
+ }
+}
+
+\ExplSyntaxOff
diff --git a/macros/latex/contrib/longdivision/longdivision_manual.pdf b/macros/latex/contrib/longdivision/longdivision_manual.pdf
new file mode 100644
index 0000000000..64a9bee6c5
--- /dev/null
+++ b/macros/latex/contrib/longdivision/longdivision_manual.pdf
Binary files differ
diff --git a/macros/latex/contrib/longdivision/longdivision_manual.tex b/macros/latex/contrib/longdivision/longdivision_manual.tex
new file mode 100644
index 0000000000..c4f23a9fbc
--- /dev/null
+++ b/macros/latex/contrib/longdivision/longdivision_manual.tex
@@ -0,0 +1,166 @@
+\documentclass{ltxdoc}
+\def\version{Version 1.1.0}
+
+\usepackage[a4paper,left=2.25cm,right=2.25cm,top=2.5cm,bottom=2.5cm,nohead]{geometry}
+\usepackage{longdivision}
+\usepackage{tikz}
+\usepackage[documentation]{tcolorbox}
+\usepackage{etoolbox}
+\usepackage{amssymb}
+\usepackage[notmath]{sansmathfonts}
+
+\usepackage{hyperref}
+\usepackage{hyperxmp}
+\hypersetup{%
+ colorlinks=true,
+ linkcolor=blue,
+ filecolor=blue,
+ urlcolor=thered,
+ citecolor=blue,
+ pdfborder=0 0 0,
+}
+
+\makeatletter % !!!!
+\input{pgfmanual.code} % This must be exectuted when catcode of @ is letter
+\makeatother % !!!!
+
+\include{pgfmanual-en-macros} % This must be executed when catcode of @ is other
+\makeatletter
+
+\MakeShortVerb{\|}
+
+%\let\pgfmanual@verb@collect@code\pgfmanual@verb@collect
+\patchcmd\pgfmanual@verb@collect{\pgfmanualprettyprintpgfkeys}{\pgfmanualprettyprintcode}{}{\error}
+%\let\pgfmanual@verb@code\pgfmanual@verb
+
+
+\patchcmd\extractkey{\hfill(\extrakeytext no value)}{}{}{\error}
+\patchcmd\extractkey{\def\mykey}{\gdef\mykey}{}{\error}
+\patchcmd\extractkeyequal{\hfill(\extrakeytext no default)}{}{}{\error}
+\patchcmd\extractkeyequal{\def\mykey}{\gdef\mykey}{}{\error}
+\patchcmd\extractinitial{no default, }{}{}{\error}
+\patchcmd\extractinitial{\def\mykey}{\gdef\mykey}{}{\error}
+\patchcmd\extractdefault{\def\mykey}{\gdef\mykey}{}{\error}
+\patchcmd\extractdefault{#2}{{\hskip2pt}#2}{}{\error}
+\patchcmd\extractequalinitial{\def\mykey}{\gdef\mykey}{}{\error}
+\let\extractkey@\extractkey
+\apptocmd\extractkey@{\egroup}{}{\error}
+\def\extractkey{\bgroup\@ifnextchar*{\def\decompose####1\nil{}\relax\extractkey@\@gobble}{\extractkey@}}
+
+% Redefine decompose not to do all that fancy crap -- just print as is. Maybe we should get rid of surrounding spaces here and where we do the ref?
+\def\decompose#1/\nil{%
+ %\index{#1@\protect\texttt{#1} key}%
+ %\index{\mypath#1@\protect\texttt{#1}}%
+ %\pgfmanualpdflabel{#1}{}%
+}
+
+\hypersetup{
+ pdftitle={The Long Division Package},
+ pdfauthor={Hood Chatham},
+ pdfsubject={A package for typesetting long division},
+ pdfkeywords={long division,math,teaching},
+ pdflicenseurl={http://www.latex-project.org/lppl/}
+}
+
+\def\today{\the\year/\the\month/\the\day}
+
+\def\@maketitle{%
+ \null\vskip 2em
+ \begin{center}\let\footnote\thanks\sffamily
+ {\huge \@title\par}\vskip 1.5em
+ {\large \parbox{.33\textwidth}{\centering\@author}%
+ \parbox{.33\textwidth}{\centering\@date}}%
+ \vskip2.5em\rule{\textwidth}{.4pt}%
+ \end{center}\par\vskip1.5em}
+\def\abstractname{}
+\def\mailtoHC{\href % some PDF viewers don't like spaces:
+ {mailto:<hood@mit.edu>\%20Hood\%20Chatham?subject=[spectralsequences\%20package]}
+ {\texttt{hood@mit.edu}}}
+\makeatother
+
+\tcbset{
+ texexp/.style={
+ skin = enhanced,
+ colframe=red!50!yellow!50!black,
+ colback=red!50!yellow!5!white,
+ coltitle=red!50!yellow!3!white,
+ segmentation style = solid,
+ fonttitle=\small\sffamily\bfseries,
+ fontupper=\small,
+ fontlower=\small},
+ texexp
+}
+\newtcblisting{texexp}[1]{texexp,#1}
+\def\longdivname{\textsc{\textsf{\textmd{longdivision}}}}
+\begin{document}
+\title{\longdivname}
+\author{Hood Chatham\\\mailtoHC}
+\date{\version\\\today}
+ \maketitle
+
+The \longdivname\ package defines two main commands: |\longdivision| and |\intlongdivision|. The usage for both is |\longdivision[|\meta{options}|]|\marg{dividend}\marg{divisor}. The difference is that |\longdivision| divides until the remainders repeat or the quotient has too many digits to fit the page, whereas |\intlongdivision| does integer division and leaves the remainder. The command |\longdivisionkeys|\marg{options} is also defined to set default options. At most 20 division steps worth of work will be displayed and at most 60 digits worth of division output will be produced. Thanks to Mike Jenck, Cameron McLeman, and Yu-Tsung Tai for emailing me with bug reports and feature requests.
+
+Here is an example usage:
+
+\begin{tcblisting}{sidebyside}
+\longdivision{100}{22}
+\quad
+\intlongdivision{100}{22}
+\end{tcblisting}
+
+These commands have several key-value options:
+
+\begin{key}{max extra digits = \meta{nonnegative integer}}
+This key determines the maximum amount of ``extra'' zeroes to add to the end of the dividend in the process of division -- if the quotient has more digits before it repeats, the division will just stop. This is only an option for |\longdivision|, the command |\intlongdivision|\marg{dividend}\marg{divisor} is equivalent to |\longdivision[max extra digits=0]|\marg{dividend}\marg{divisor}. For brevity, this option has the short form where just the value is provided: |\longdivision[2]|\marg{dividend}\marg{divisor} is the same as |\longdivision[max extra digits=2]|\marg{dividend}\marg{divisor}.
+
+\begin{tcblisting}{}
+\longdivision[max extra digits = 2]{10.0}{7} \quad
+\longdivision[1]{10.0}{7}
+\end{tcblisting}
+\end{key}
+
+
+\begin{key}{stage = \meta{nonnegative integer}}
+This controls how many steps worth of division to do. Thanks to Cam McLeman for suggesting this feature.
+\begin{tcblisting}{}
+\longdivision[stage=0]{1}{7} \quad
+\longdivision[stage=1]{1}{7} \quad
+\longdivision[stage=2]{1}{7} \quad
+\longdivision[stage=3]{1}{7} \quad
+\longdivision[stage=4]{1}{7} \quad
+\longdivision[stage=5]{1}{7} \quad
+\longdivision[stage=6]{1}{7}
+\end{tcblisting}
+\end{key}
+
+\begin{key}{style = \meta{style}}
+Control the style for typesetting the result of long division. The options are |default|, |standard|, |tikz|, or |german|. The option |default| is the same as |tikz| if \tikzname\ is loaded and otherwise is the same as |standard|. You probably should load \tikzname\ because the \tikzname\ version looks significantly better. If you use this option, you'll probably want to set the style once and for all in your preamble with |\longdivisionkeys{style=|\meta{style}|}|.
+\begin{tcblisting}{}
+\intlongdivision[style = tikz ]{100.0}{13} \quad
+\intlongdivision[style = standard]{100.0}{13} \quad
+\intlongdivision[style = german ]{100.0}{13}
+\end{tcblisting}
+You can define your own typesetting style by saying |\longdiv_define_style:nn|\marg{style name}\marg{code}. This can use the commands |\longdivdividend| which contains the dividend, |\longdivdivisor| which contains the divisor, |\longdivquotient| which contains the quotient, and |\longdivwork:| which contains the |division work|. For instance, a simplified version of the |german| style is:
+\begin{tcblisting}{}
+\longdivdefinestyle{my style}{%
+ \begin{tabular}{@{}l@{}}
+ \longdivdividend : \, \longdivdivisor \, = \longdivquotient \\
+ \longdivwork
+ \end{tabular}
+}
+\longdivision[style = my style]{2}{3}
+\end{tcblisting}
+Send me an email if you cannot figure out how to make a style to your liking.
+\end{key}
+
+\begin{key}{repeating decimal style = \meta{style}}
+Control the way that repeating decimals are typeset. The options are |overline|, |dots|, |dots all|, |parentheses|, or |none|. The default is |overline|. The |parentheses| style creates ugly spacing problems and the |dots| style is insufficiently visible, so the |overline| style is the best. If you use this option, you'll probably want to set the style once and for all in your preamble with |\longdivisionkeys{recurring decimal style=|\meta{style}|}| |\longdivisionkeys{style=|\meta{style}|}|. Like the |style| key, this is designed to be extensible. However, the process of creating new |repeating decimal style|s is a bit involved. Send me an email if you want a new |repeating decimal style|.
+\begin{tcblisting}{}
+\longdivision[repeating decimal style = overline ]{5.3}{37} \quad
+\longdivision[repeating decimal style = dots ]{5.3}{37} \quad
+\longdivision[repeating decimal style = dots all ]{5.3}{37} \quad
+\longdivision[repeating decimal style = parentheses]{5.3}{37} \quad
+\longdivision[repeating decimal style = none ]{5.3}{37}
+\end{tcblisting}
+\end{key}
+\end{document}