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}

enter image description here

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
  }
\]

enter image description here

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}

enter image description here


I just did three rows here but

enter image description here

\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)}

Output

\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}