Visualize multiple string segments
The syntax of the proposed command is
\segments[<width>]{<string>}{<segments>;<segments>;...}
where <width>
is the width of the cells (default 1em), <string>
is the string to typeset and <segments>
is a list of cells to underline. Such a list consists of single numbers or <number>-<number>
to mean the cells to straddle.
Note that this ignores spaces in both arguments (but ranges should be typed in without spaces), so the example can also be typed in like
\segments{1 0 1 0 0 1 0 0}{
1, 2, 3, 4, 5, 6, 7, 8 ;
1-3, 4-5, 7-8 ;
4-8
}
if preferred.
\documentclass{article}
\usepackage{xparse,array,booktabs}
\ExplSyntaxOn
\NewDocumentCommand{\segments}{O{1em}mm}
{% #1 = width of cells, #2 = string, #3 = list of underlines
\group_begin:
\renewcommand{\arraystretch}{0}
\fizruk_segments:n { #3 }
\begin{tabular}[t]{ @{} *{ \tl_count:n { #2 } }{ w{c}{#1} @{} } }
\seq_set_split:Nnn \l__fizruk_string_seq { } { #2 }
\seq_use:Nn \l__fizruk_string_seq { & } \\
\tl_use:N \l__fizruk_segments_tl
\end{tabular}
\group_end:
}
\seq_new:N \l__fizruk_string_seq
\seq_new:N \l__fizruk_stages_seq
\tl_new:N \l__fizruk_segments_tl
\cs_new_protected:Nn \fizruk_segments:n
{
\tl_clear:N \l__fizruk_segments_tl
\seq_set_split:Nnn \l__fizruk_stages_seq { ; } { #1 }
\seq_map_function:NN \l__fizruk_stages_seq \__fizruk_segment_row:n
}
\cs_new_protected:Nn \__fizruk_segment_row:n
{
\clist_map_function:nN { #1 } \__fizruk_add_segment:n
\tl_put_right:Nn \l__fizruk_segments_tl { \morecmidrules }
}
\cs_new_protected:Nn \__fizruk_add_segment:n
{
\str_if_in:nnTF { #1 } { - }
{
\tl_put_right:Nn \l__fizruk_segments_tl { \cmidrule(l{2pt}r{2pt}){#1} }
}
{
\tl_put_right:Nn \l__fizruk_segments_tl { \cmidrule(l{2pt}r{2pt}){#1-#1} }
}
}
\ExplSyntaxOff
\begin{document}
\[
S=\segments{10100100}{1,2,3,4,5,6,7,8;1-3,4-5,7-8; 4-8}
\]
\end{document}
Here's the output of
\[
S=\segments{10100100}{
1-3,4-8;
1,2-7,8;
2-4,5-7;
2,3-6,7-8;
3,4-5,6,7;
4,5
}
\]
With the following modification, you can insert a line between two symbols, denote it by .3
if you want it to follow the third symbol.
\documentclass{article}
\usepackage{xparse,array,booktabs}
\ExplSyntaxOn
\NewDocumentCommand{\segments}{O{1em}mm}
{% #1 = width of cells, #2 = string, #3 = list of underlines
\group_begin:
\renewcommand{\arraystretch}{0}
\dim_set:Nn \l__fizruk_cell_dim { #1 }
\fizruk_segments:n { #3 }
\tl_show:N \l__fizruk_segments_tl
\begin{tabular}[t]{ @{} *{ \tl_count:n { #2 } }{ w{c}{#1} @{} } }
\seq_set_split:Nnn \l__fizruk_string_seq { } { #2 }
\seq_use:Nn \l__fizruk_string_seq { & } \\
\tl_use:N \l__fizruk_segments_tl
\end{tabular}
\group_end:
}
\dim_new:N \l__fizruk_cell_dim
\seq_new:N \l__fizruk_string_seq
\seq_new:N \l__fizruk_stages_seq
\tl_new:N \l__fizruk_segments_tl
\cs_new_protected:Nn \fizruk_segments:n
{
\tl_set:Nn \l__fizruk_segments_tl { \addlinespace[3pt] }
\seq_set_split:Nnn \l__fizruk_stages_seq { ; } { #1 }
\seq_map_function:NN \l__fizruk_stages_seq \__fizruk_segment_row:n
}
\cs_new_protected:Nn \__fizruk_segment_row:n
{
\clist_map_function:nN { #1 } \__fizruk_add_segment:n
\tl_put_right:Nn \l__fizruk_segments_tl { \morecmidrules }
}
\cs_new_protected:Nn \__fizruk_add_segment:n
{
\str_if_in:nnTF { #1 } { - }
{
\tl_put_right:Nx \l__fizruk_segments_tl { \__fizruk_cmidrule:nn { /5 } { #1 } }
}
{
\str_if_in:nnTF { #1 } { . }
{
\tl_put_right:Nx \l__fizruk_segments_tl
{
\__fizruk_cmidrule:ne { *4/5 } { \tl_tail:n { #1 }-\int_eval:n { \tl_tail:n { #1 }+1 } }
}
}
{
\tl_put_right:Nx \l__fizruk_segments_tl { \__fizruk_cmidrule:nn { /5 } { #1-#1 } }
}
}
}
\cs_new:Nn \__fizruk_cmidrule:nn
{
\exp_not:N\cmidrule(l{\dim_eval:n{\l__fizruk_cell_dim #1}}r{\dim_eval:n{\l__fizruk_cell_dim #1}}){#2}
}
\cs_generate_variant:Nn \__fizruk_cmidrule:nn { ne }
\ExplSyntaxOff
\begin{document}
\[
S=\segments{10100100}{1,2,3,4,5,6,7,8;1-3,4-5,7-8; 4-8}
\]
\[
S=\segments{10100100}{
1-3,4-8;
1,2-7,8;
2-4,5-7;
2,3-6,7-8;
3,4-5,6,7;
4,5
}
\]
\[
S = \segments{1 0 1 0 0 1 0 0}{
.3;
3,4;
2-4,5-7
}
\]
\end{document}
I just did three rows here but
\documentclass{article}
\usepackage{booktabs}
\begin{document}
\[
\begin{array}{r@{}*{10}{c}}
S={}&1&0&1&0&0&1&0&0 \\
\cmidrule(r){2-4}\cmidrule(l){5-9}
\morecmidrules
\cmidrule(r){2-2}\cmidrule(lr){3-8}\cmidrule(l){9-9}
\morecmidrules
\cmidrule(r){3-5}\cmidrule(l){6-7}
\end{array}
\]
\end{document}
A solution using tikZ. The notation goes as follows:
in \ourInfo
array, each cell corresponds to: {level, starting character index (including), finish character index(including)}
\documentclass[margin=1cm, tikz]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=0.5]
\def\binaryString{{1, 0, 1, 0, 0, 1, 0, 0}}
%Notation: {level, starting character index (including), finish character index(including)}
%NOTE! Everyting is zero-based
\def\ourInfo{{
% Level 0
{0,0,2},{0,3,7},
% Level 1
{1,0,0},{1,1,6},{1,7,7},
% Level 2
{2,1,3},{2,4,7},
% Level 3
{3,1,1},{3,2,5},{3,6,7},
% Level 4
{4,2,2},{4,3,4},{4,5,5},{4,6,6},
% Level 5
{5,3,3},{5,4,4}
}}
\pgfmathsetmacro{\length}{15}% Zero based.
\foreach \i in {0, ..., 7}{
\draw[] (\i,0) node{\pgfmathparse{\binaryString[\i]}\pgfmathresult};
}
\foreach \i in {0, ..., \length}{
\pgfmathsetmacro{\level}{\ourInfo[\i][0]}
\pgfmathsetmacro{\start}{\ourInfo[\i][1]}
\pgfmathsetmacro{\finish}{\ourInfo[\i][2]}
\draw[thick] (\start-0.3,-0.5-\level/2)--(\finish+0.3,-0.5-\level/2){};
}
\end{tikzpicture}
\end{document}