summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/returntogrid/returntogrid.sty
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/returntogrid/returntogrid.sty
Initial commit
Diffstat (limited to 'macros/latex/contrib/returntogrid/returntogrid.sty')
-rw-r--r--macros/latex/contrib/returntogrid/returntogrid.sty428
1 files changed, 428 insertions, 0 deletions
diff --git a/macros/latex/contrib/returntogrid/returntogrid.sty b/macros/latex/contrib/returntogrid/returntogrid.sty
new file mode 100644
index 0000000000..64aaa92b49
--- /dev/null
+++ b/macros/latex/contrib/returntogrid/returntogrid.sty
@@ -0,0 +1,428 @@
+\RequirePackage{xparse}
+
+\ProvidesExplPackage {returntogrid} {2018/08/21} {0.2}
+ {return to a grid position}
+% \debug_on:n { check-expressions,deprecation } % needs enable-debug
+\RequirePackage{eso-pic}
+\RequirePackage{zref-savepos,zref-abspage}
+
+\msg_new:nnn {ufgrid} {tikz-needed} { the~showdebugpagegrid~command~needs~the~tikz~package }
+\msg_new:nnn {ufgrid} {tab-list-unknown} { the~tab~list~"#1"~has~not~been~declared}
+
+\sys_if_engine_luatex:T
+{
+ \directlua{require ("returntogrid.lua")}
+}
+
+\int_new:N \l__ufgrid_vskip_int %vskip in sp
+\int_new:N \g__ufgrid_vpoint_int %for the v-labels
+\int_new:N \g__ufgrid_hpoint_int %for the h-labels of tabs
+\int_new:N \l__ufgrid_tempa_int
+\int_new:N \l__ufgrid_tab_cor_int
+
+\bool_new:N \g__ufgrid_active_bool
+\bool_gset_true:N \g__ufgrid_active_bool
+\bool_new:N \l__ufgrid_hmode_bool %hmode (tabs)
+\bool_new:N \l__ufgrid_savepos_bool %save position
+\bool_new:N \l__ufgrid_insert_vskip_bool %insert vskip
+\bool_new:N \l__ufgrid_autolabel_bool %numbered labels
+\bool_new:N \l__ufgrid_tabfound_bool
+\bool_new:N \l__ufgrid_hfill_bool
+\bool_new:N \l__ufgrid_debug_tab_bool
+\bool_new:N \g__ufgrid_twoside_bool
+
+\if@twoside \bool_gset_true:N \g__ufgrid_twoside_bool \fi
+
+\tl_new:N \l__ufgrid_setup_step_tl %step value (dim in sp)
+\tl_new:N \l__ufgrid_setup_reference_tl %name of reference point
+\tl_new:N \l__ufgrid_setup_offset_tl %an offset, e.g. topskip
+\tl_new:N \l__ufgrid_label_tl %holds the label name
+\tl_new:N \l__ufgrid_curpos_tl
+\tl_new:N \g__ufgrid_prefix_vpoint_tl %prefix of v-point labels
+\tl_new:N \g__ufgrid_prefix_tabpos_tl %prefix for tab positions
+\tl_new:N \g__ufgrid_prefix_hpoint_tl %prefix for h-point labels
+\tl_new:N \g__ufgrid_prefix_user_tl %prefix for labels provided by the user
+\tl_new:N \l__ufgrid_tab_list_tl %holds the name of the current tab list
+\tl_new:N \l__ufgrid_debug_tab_draw_tl %hold the draw command to debug tab positions
+\tl_new:N \l__ufgrid_tmp_vskip_tl % to pass the vskip to zsavepos
+
+\dim_new:N \l__ufgrid_debug_tab_dim
+
+\prop_new:N \g__ufgrid_vskip_prop %will hold the vskips by label name
+
+\cs_generate_variant:Nn \prop_gput:Nnn {Nxx}
+\cs_generate_variant:Nn \prop_get:NnNTF {NxNTF}
+\cs_generate_variant:Nn \prop_get:NnNF {NxNF}
+
+% we need to store the current displacement
+\zref@newprop {ufgridvskip}[0]{\int_use:N \l__ufgrid_vskip_int}
+\zref@newprop*{pagecnt} [1] {\the\c@page}
+\zref@addprop {savepos} {ufgridvskip}
+\zref@addprop {savepos} {abspage}
+\zref@addprop {savepos} {pagecnt}
+
+
+\keys_define:nn { ufgrid / setup}
+{
+ activate .bool_gset:N = \g__ufgrid_active_bool,
+ % step = dimension
+ step .code:n = { \tl_set:Nx \l__ufgrid_setup_step_tl { \dim_to_decimal_in_sp:n {#1} } },
+ % reference = labelname (label should be set with zsavepos)
+ reference .tl_set:N = \l__ufgrid_setup_reference_tl,
+ % offset = dimension: move down (example offset= \topskip)
+ offset .code:n = { \tl_set:Nx \l__ufgrid_setup_offset_tl { \dim_to_decimal_in_sp:n {#1} } },
+ tab-list .tl_set:N = \l__ufgrid_tab_list_tl,
+ settabpositions .code:n = { \__ufgrid_settabpositions:nn #1 },
+ prefix-vpoint .tl_gset:N = \g__ufgrid_prefix_vpoint_tl,
+ prefix-tabpos .tl_gset:N = \g__ufgrid_prefix_tabpos_tl,
+ prefix-hpoint .tl_gset:N = \g__ufgrid_prefix_hpoint_tl,
+ prefix-user .tl_gset:N = \g__ufgrid_prefix_user_tl,
+ debug-tab .bool_set:N= \l__ufgrid_debug_tab_bool,
+ debug-tab-len .dim_set:N = \l__ufgrid_debug_tab_dim,
+ debug-tab-draw .tl_set:N = \l__ufgrid_debug_tab_draw_tl,
+ hmode .bool_set:N= \l__ufgrid_hmode_bool,
+ hfill .bool_set:N= \l__ufgrid_hfill_bool,
+ tab .code:n =
+ {
+ \tl_if_empty:nF { #1 }
+ {
+ \tl_set:Nn \l__ufgrid_tab_list_tl {#1}
+ }
+ \bool_set_true:N \l__ufgrid_hmode_bool
+ },
+ twoside .bool_gset:N = \g__ufgrid_twoside_bool
+}
+
+\normalsize %just in case
+\keys_set:nn { ufgrid / setup }
+ {
+ prefix-vpoint = ufgrid@vpoint,
+ prefix-tabpos = ufgrid@tabpos,
+ prefix-hpoint = ufgrid@hpoint,
+ prefix-user = ufgrid@user,
+ step = \baselineskip,
+ reference = \g__ufgrid_prefix_vpoint_tl textupperleft,
+ offset = \topskip,
+ debug-tab-len = -4cm,
+ debug-tab-draw= { \draw[blue,dashed] (0,1em)--++(0,\l__ufgrid_debug_tab_dim) },
+ hfill
+ }
+
+
+\keys_define:nn { ufgrid / use }
+ {
+ __savepos .bool_set:N = \l__ufgrid_savepos_bool,
+ __insert_vskip .bool_set:N = \l__ufgrid_insert_vskip_bool,
+ __label .tl_set:N = \l__ufgrid_label_tl,
+ __autolabel .bool_set:N = \l__ufgrid_autolabel_bool,
+ save .meta:n = { __label=\g__ufgrid_prefix_user_tl#1, __savepos=true, __insert_vskip=false,__autolabel=false },
+ save .value_required:n = true,
+ label .meta:n = { __label=\g__ufgrid_prefix_user_tl#1, __autolabel=false },
+ label .value_required:n = true,
+ use .meta:n =
+ {
+ __label=\g__ufgrid_prefix_user_tl#1, __savepos=false, __insert_vskip=true,__autolabel=false
+ },
+ use .value_required:n = true,
+ strut .code:n = \__ufgrid_insert_ufgridstrut:n { #1 },
+ hmode .bool_set:N = \l__ufgrid_hmode_bool,
+ tab-list .tl_set:N = \l__ufgrid_tab_list_tl,
+ tab .code:n =
+ {
+ \tl_if_empty:nF { #1 }
+ {
+ \tl_set:Nn \l__ufgrid_tab_list_tl {#1}
+ }
+ \bool_set_true:N \l__ufgrid_hmode_bool
+ },
+ debug-vgrid .code:n = {\AddToShipoutPictureBG*{\AtTextUpperLeft{\showdebugpagegrid}}}
+ }
+
+
+%%calculate the vskip to insert
+ %#1 = diff to a point on the grid
+ %#2 = currently used vskip,
+ %#3 = step
+ % all values integers =dim in sp!
+\sys_if_engine_luatex:TF
+ {
+ \cs_new:Nn \__ufgrid_calculate_vskip:nnn
+ { \directlua { returntogrid.ufgridvskip (#1,#2,#3) } }
+ }
+ {
+ \cs_new:Nn \__ufgrid_calculate_vskip:nnn
+ {
+ \int_eval:n
+ {
+ \int_mod:nn
+ {
+ #2 + #3 - \int_mod:nn { #1 }{ #3 }
+ }
+ {#3}
+ }
+ }
+ }
+
+
+\cs_new:Nn \__ufgrid_calculate_vskip:n %#1 =labelname
+ {
+ \__ufgrid_calculate_vskip:nnn
+ { %diff
+ \zposy{\l__ufgrid_setup_reference_tl} - \l__ufgrid_setup_offset_tl - \zposy{#1}
+ }
+ { %current vskip
+ \zref@extractdefault{#1-vskip} {ufgridvskip} {0}
+ }
+ {
+ \l__ufgrid_setup_step_tl
+ }
+ }
+
+\cs_new_protected:Nn \__ufgrid_savepos:n %#1 label name
+ {
+ \leavevmode\strut
+ \zsavepos{#1}
+ }
+
+
+\cs_new_protected:Nn \__ufgrid_insert_vskip:n %#1 label name
+ {
+ \par
+ \int_compare:nT { \zposy{#1} != 0 }
+ {
+ %calculate the needed vskip base on the ypos and the old vskip
+ \int_set:Nn \l__ufgrid_vskip_int
+ {
+ \__ufgrid_calculate_vskip:n { #1 }
+ }
+ \zref@labelbyprops {#1-vskip}{ufgridvskip}
+ %insert the vskip
+ \vspace*{\l__ufgrid_vskip_int sp}
+ %\vskip \l__ufgrid_vskip_int sp\relax
+ %\vskip 0pt
+ }
+ }
+
+\cs_new_protected:Nn \__ufgrid_insert_ufgridstrut:n {\rule{0pt}{\dim_eval:n { \l__ufgrid_setup_step_tl sp + \topskip }}}
+
+
+%vertical version
+\cs_new_protected:Nn \__ufgrid_returntogrid_v:
+{
+ \bool_if:NT \l__ufgrid_autolabel_bool
+ {
+ \int_gincr:N \g__ufgrid_vpoint_int
+ \tl_set:Nn \l__ufgrid_label_tl
+ {
+ \g__ufgrid_prefix_vpoint_tl \int_use:N\g__ufgrid_vpoint_int
+ }
+ }
+ \bool_if:NT\l__ufgrid_insert_vskip_bool
+ {
+ \__ufgrid_insert_vskip:n { \l__ufgrid_label_tl }
+ }
+ \bool_if:NT\l__ufgrid_savepos_bool
+ {
+ \__ufgrid_savepos:n { \l__ufgrid_label_tl }
+ }
+}
+
+
+\cs_new_protected:Nn \__ufgrid_settabpositions:nn %#1 name #2 list of spaces
+ {
+ \seq_set_from_clist:Nn \l_tmpa_seq {#2}
+ \seq_new:c {g__ufgrid_tabpos_#1_seq}
+ \int_set:Nn\l__ufgrid_tempa_int {1}
+ \makebox[0pt][l]
+ {
+ \seq_map_inline:Nn \l_tmpa_seq
+ {
+ \zsavepos{\g__ufgrid_prefix_tabpos_tl#1\int_use:N\l__ufgrid_tempa_int}
+ \bool_if:NT \l__ufgrid_debug_tab_bool
+ {
+ \__ufgrid_debug_showtabs:n { #1 }
+ }
+ \hspace*{\dim_eval:n{##1}}
+ \int_incr:N\l__ufgrid_tempa_int
+ }
+ \zsavepos{\g__ufgrid_prefix_tabpos_tl#1\int_use:N\l__ufgrid_tempa_int}
+ \bool_if:NT \l__ufgrid_debug_tab_bool
+ {
+ \__ufgrid_debug_showtabs:n { #1 }
+ }
+ \int_step_inline:nnnn {1}{1}{\l__ufgrid_tempa_int}
+ {
+ \seq_gput_right:cx {g__ufgrid_tabpos_#1_seq} {\zposx{\g__ufgrid_prefix_tabpos_tl#1##1}}
+ }
+ }
+ }
+
+
+
+\cs_new_protected:Nn \__ufgrid_returntogrid_h:n %#1 name
+{
+ \seq_if_exist:cF { g__ufgrid_tabpos_#1_seq }
+ {
+ \msg_error:nnx { ufgrid } {tab-list-unknown} { #1}
+ }
+ \bool_if:NT \l__ufgrid_autolabel_bool
+ {
+ \int_gincr:N \g__ufgrid_hpoint_int
+ \tl_set:Nn \l__ufgrid_label_tl
+ {
+ \g__ufgrid_prefix_hpoint_tl \int_use:N\g__ufgrid_hpoint_int
+ }
+ }
+ \leavevmode\zsavepos{\l__ufgrid_label_tl}
+ \tl_set:Nx \l__ufgrid_curpos_tl
+ {
+ \zref@extractdefault {\l__ufgrid_label_tl} {posx} {-1}
+ }
+ \bool_if:NT \g__ufgrid_twoside_bool
+ {
+ \int_if_odd:nTF
+ {
+ \zref@extractdefault {\l__ufgrid_label_tl} {pagecnt} {1}
+ -
+ \zref@extractdefault {\g__ufgrid_prefix_tabpos_tl#1 1} {pagecnt} {1}
+ }
+ {
+ % tab setting and current pos are on different page types.
+ \int_if_even:nTF
+ {
+ \zref@extractdefault {\g__ufgrid_prefix_tabpos_tl#1 1} {pagecnt} {1}
+ }
+ {
+ \int_set:Nn \l__ufgrid_tab_cor_int {\dim_to_decimal_in_sp:n {\oddsidemargin-\evensidemargin}}
+ }
+ {
+ \int_set:Nn \l__ufgrid_tab_cor_int {\dim_to_decimal_in_sp:n {\evensidemargin-\oddsidemargin}}
+ }
+ }
+ {
+ \int_set:Nn \l__ufgrid_tab_cor_int {0}
+ }
+ }
+ \int_compare:nNnF { \l__ufgrid_curpos_tl } {=}{-1}
+ {
+ \bool_set_false:N \l__ufgrid_tabfound_bool
+ \int_step_inline:nn { \seq_count:c { g__ufgrid_tabpos_#1_seq }-1 }
+ {
+ \int_compare:nT
+ { (\seq_item:cn { g__ufgrid_tabpos_#1_seq } { ##1 } + \l__ufgrid_tab_cor_int)
+ <
+ \l__ufgrid_curpos_tl
+ <
+ (\seq_item:cn { g__ufgrid_tabpos_#1_seq } { ##1 +1 } + \l__ufgrid_tab_cor_int)
+ }
+ {
+ \bool_set_true:N \l__ufgrid_tabfound_bool
+ \hspace*
+ {
+ \int_eval:n
+ {
+ \seq_item:cn { g__ufgrid_tabpos_#1_seq } { ##1 +1 } + \l__ufgrid_tab_cor_int
+ -
+ \l__ufgrid_curpos_tl
+ }sp
+ }
+ }
+ }
+ \bool_if:NT \l__ufgrid_hfill_bool
+ {
+ \int_step_inline:nn { \seq_count:c { g__ufgrid_tabpos_#1_seq }}
+ {
+ \int_compare:nT
+ {
+ \seq_item:cn { g__ufgrid_tabpos_#1_seq } { ##1 } + \l__ufgrid_tab_cor_int
+ =
+ \l__ufgrid_curpos_tl
+ }
+ {
+ \bool_set_true:N \l__ufgrid_tabfound_bool
+ }
+ }
+ \bool_if:NF \l__ufgrid_tabfound_bool {\hfill}
+ }
+ }
+}
+
+
+
+\cs_new_protected:Nn \__ufgrid_returntogrid:n
+{
+ \group_begin:
+ \bool_if:NT \g__ufgrid_active_bool
+ {
+ \keys_set:nn { ufgrid / use }
+ {
+ __autolabel,__savepos=true,__insert_vskip=true,hmode=false,
+ #1
+ }
+ \bool_if:NTF \l__ufgrid_hmode_bool
+ {
+ \__ufgrid_returntogrid_h:n { \l__ufgrid_tab_list_tl }
+ }
+ {
+ \__ufgrid_returntogrid_v:
+ }
+ }
+ \group_end:
+}
+
+
+\NewDocumentCommand\returntogrid{ O {} }
+ {
+ \__ufgrid_returntogrid:n { #1 }
+ }
+
+
+
+
+\NewDocumentCommand\returntogridsetup { m }
+ {
+ \keys_set:nn { ufgrid / setup } { #1}
+ }
+
+\NewDocumentCommand \showdebugpagegrid {}
+ {
+ \cs_if_exist:NTF\tikzpicture
+ {
+ \begin{tikzpicture}[overlay]
+ \draw[dotted,red]
+ (0,0) --++ (\textwidth,0cm);
+ \tl_set:Nx \l_tmpa_tl {\fp_eval:n {
+ trunc (
+ (\dim_to_decimal_in_sp:n {\textheight} - \l__ufgrid_setup_offset_tl )
+ /
+ \l__ufgrid_setup_step_tl
+ )
+ }}
+ \foreach\x in {0,1,2,...,\l_tmpa_tl}
+ {
+ \draw[red,dashed]
+ (0,\fp_eval:n {-\l__ufgrid_setup_offset_tl-(\x*\l__ufgrid_setup_step_tl)}sp) --++ (\textwidth,0cm);
+ }
+ \end{tikzpicture}%
+ }
+ {
+ \msg_warning:nn {ufgrid} {tikz-needed}
+ }
+ }
+
+\cs_new_protected:Nn \__ufgrid_debug_showtabs:n
+{
+ \cs_if_exist:NTF\tikzpicture
+ {
+ \tikz[overlay]
+ \l__ufgrid_debug_tab_draw_tl;
+ }
+ {
+ \msg_warning:nn {ufgrid} {tikz-needed}
+ }
+ }
+
+
+\AddToShipoutPictureBG*{\AtTextUpperLeft{\zsaveposy{\g__ufgrid_prefix_vpoint_tl textupperleft}}}
+
+ \endinput