<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">%%% ----------------------------------------------------------------------------
%%% pascaltriangle: Typeset Pascal triangle figure with LaTeX3
%%% Author    : Nan Geng &lt;nangeng@nwafu.edu.cn&gt;
%%% Repository: https://github.com/registor/pascaltriangle or https://gitee.com/nwafu_nan/pascaltriangle
%%% License   : The LaTeX Project Public License 1.3c
%%% ----------------------------------------------------------------------------

\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3}
\ProvidesExplPackage{pascaltriangle}{2022-01-28}{v1.0.1}
  {Typeset Pascal triangle figure with LaTeX3}

\RequirePackage{xparse}

%% \tl_if_eq:NnTF ä¸Žtexlive 2020çš„å…¼å®¹æ€§è®¾ç½®
\cs_if_exist:NF \tl_if_eq:NnTF
  {
    \tl_new:N \l__tblr_backport_b_tl
    \prg_new_protected_conditional:Npnn \tl_if_eq:Nn #1 #2 { T, F, TF }
      {
        \group_begin:
          \tl_set:Nn \l__tblr_backport_b_tl {#2}
          \exp_after:wN
        \group_end:
        \if_meaning:w #1 \l__tblr_backport_b_tl
          \prg_return_true:
        \else:
          \prg_return_false:
        \fi:
      }
    \prg_generate_conditional_variant:Nnn \tl_if_eq:Nn { c } { TF, T, F }
  }

\cs_if_exist:NF \seq_map_indexed_function:NN
  {
    \cs_set_eq:NN \seq_map_indexed_function:NN \seq_indexed_map_function:NN
  }

%% è§£å†³TikZåº“æ—&nbsp;æ³•åœ¨Expl3ä¸­è½½å…¥é—®é¢˜
\RequirePackage {amsmath, tikz, etoolbox}
\ExplSyntaxOff
\patchcmd
{\tcb@input@library@in}
  {%
   \input\tcbpkgprefix#1\relax%
  }
  {%
    \@pushfilename
    \input\tcbpkgprefix#1\relax%
    \@popfilename
  }
  {}{}

\patchcmd
{\pgfutil@InputIfFileExists}
  {\input #1}
  {%
    \@pushfilename
    \xdef\@currname{#1}%
    \input #1 %
    \@popfilename
  }
  {}{}
\ExplSyntaxOn
\usetikzlibrary{shapes.geometric}

%% å®šä¹‰å˜é‡
\bool_new:N  \l__pascal_num_cell_bool   % æ˜¯å¦ç»˜åˆ¶è¡Œåˆ—å·
\bool_new:N  \l__pascal_binom_cell_bool % æ˜¯å¦ä»…ç»˜åˆ¶äºŒé¡¹å¼è¡¨è¾¾å¼

\tl_new:N    \l__pascal_cell_color_tl   % å•å…ƒæ&nbsp;¼å¡«å……é¢œè‰²
\tl_new:N    \l__pascal_shift_col_pt_tl % åˆ—å˜æ¢åæ&nbsp;‡
\tl_new:N    \l__pascal_shift_row_pt_tl % è¡Œå˜æ¢åæ&nbsp;‡
\tl_new:N    \l__pascal_font_size_tl    % æ–‡ä»¶å¤§å°

\int_new:N    \l__pascal_shape_type_int % å½¢çŠ¶(1---ç­‰è…°ï¼Œ2---ç›´è§’)
\int_new:N    \l__pascal_row_idx_int    % è¡Œç´¢å¼•(ä»Ž0è®¡æ•°)
\int_new:N    \l__pascal_col_idx_int    % åˆ—ç´¢å¼•(ä»Ž0è®¡æ•°)
\int_new:N    \l__pascal_row_top_int    % å„åˆ—æœ€å¤§è¡Œæ•°
\int_new:N    \l__pascal_total_idx_int  % ç´¢å¼•æ€»æ•°
\int_new:N    \l__pascal_fill_row_int   % å¡«å……è¡Œå·(æœ€å¤§å€¼ä¸Žå½“å‰åˆ—æ•°æœ‰å…³ï¼Œä»Žé¡¶å‘ä¸‹ä»Ž0è®¡æ•°)
\int_new:N    \l__pascal_fill_col_int   % å¡«å……åˆ—å·(ä»Ž0è®¡æ•°)

\dim_new:N    \l__pascal_cell_radius_dim % å•å…ƒæ&nbsp;¼å¤§å°(ä¸­å¿ƒåˆ°é¡¶ç‚¹çš„åŠå¾„)

%% é€‰é¡¹è®¾è®¡
\keys_define:nn { pascal }
  {
    % æ˜¯å¦éœ€è¦è¡Œåˆ—ç¼–å·
    withnum .bool_set:N = \l__pascal_num_cell_bool,
    withnum .default:n = true,
    withnum .initial:n = false,

    % æ˜¯å¦ä»…ç»˜åˆ¶äºŒé¡¹å¼è¡¨è¾¾å¼
    binom .bool_set:N = \l__pascal_binom_cell_bool,
    binom .default:n = true,
    binom .initial:n = false,

    % å½¢çŠ¶é€‰æ‹©(iso---ç­‰è…°ä¸‰è§’å½¢, rt---ç›´è§’ä¸‰è§’å½¢)
    shape .choice:,
    shape .value_required:n = true,
    shape .choices:nn =
      { iso, rt }
      { \int_set_eq:NN \l__pascal_shape_type_int \l_keys_choice_int },
    shape .initial:n = iso,

    % å•å…ƒæ&nbsp;¼åŠå¾„(ä¸­å¿ƒåˆ°é¡¶ç‚¹)
    radius .dim_set:N  = \l__pascal_cell_radius_dim,
    radius .initial:n = 0.5cm,

    % æ–‡å­—å¤§å°
    fontsize .tl_set:N  = \l__pascal_font_size_tl,
    fontsize .initial:n = \small,

    % è¦å¡«å……å•å…ƒæ&nbsp;¼è¡Œæ•°(æŒ‰åˆ—ä»Žé¡¶å‘ä¸‹ï¼Œä»Ž0å¼€å§‹è®¡æ•°)
    fillr .int_set:N = \l__pascal_fill_row_int,
    fillr .initial:n = 1 ,
    % è¦å¡«å……å•å…ƒæ&nbsp;¼åˆ—æ•°(ä»Žå·¦å‘å³ï¼Œä»Ž0å¼€å§‹è®¡æ•°)
    fillc .int_set:N = \l__pascal_fill_col_int,
    fillc .initial:n = 1 ,
    fillrc  .meta:n = { fillr = #1 , fillc = #1 },

    unknown .code:n = { \__pascal_error:n { unknown-option } }
  }

\msg_new:nnn { pascal } { unknown-option }
  { package~ option~ "\l_keys_key_tl"~ is~ unknown. }

%% å‚æ•°è®¾ç½®ç”¨æˆ·æŽ¥å£
\NewDocumentCommand \pascalset { m }
  { \keys_set:nn { pascal } {#1} }

%% åˆ©ç”¨LaTeX3çš„facté˜¶ä¹˜è®¡ç®—å‡½æ•°è®¡ç®—ç»„åˆæ•°
\cs_set:Npn \__pascal_binomcoeff:nn #1#2
  {
    \fp_eval:n { fact(#1) / (fact(#2) * fact(#1 - #2)) }
  }

%% ç»„åˆæ•°è®¡ç®—ç”¨æˆ·æŽ¥å£
\NewDocumentCommand{\binomc}{m m}
  {
    \__pascal_binomcoeff:nn{#1}{#2}
  }

%% ç»˜åˆ¶Pascalä¸‰è§’å½¢
%% æ³¨æ„":"æ—&nbsp;æ³•ä½¿ç”¨é€&nbsp;æˆæžåæ&nbsp;‡ä¸èƒ½ç”¨çš„é—®é¢˜ï¼Œä»¥ä¸‹ç½‘ç«™ç»™å‡ºäº†è§£å†³æ–¹æ¡ˆ
%% https://tex.stackexchange.com/questions/501333/how-to-use-colon-as-part-of-tikz-syntax-while-in-explsyntaxon-environment
%% å°†":"ç”¨\c_colon_strä»£æ›¿

%% æ&nbsp;¹æ®å½¢çŠ¶ç±»åž‹è®¡ç®—åˆ—å˜æ¢åæ&nbsp;‡(æžåæ&nbsp;‡)
\cs_set:Npn \__pascal_shift_col_pt:n #1
  {
    \int_case:nn { \l__pascal_shape_type_int }
      {
        {1}{
          \tl_set:Nn \l__pascal_shift_col_pt_tl { -60 \c_colon_str
              \fp_eval:n {sqrt(3) * \l__pascal_cell_radius_dim * #1}pt
            }
        }
        {2}{
          \tl_set:Nn \l__pascal_shift_col_pt_tl { -45 \c_colon_str
              \fp_eval:n {2 * \l__pascal_cell_radius_dim * #1}pt
            }
        }
      }
  }

%% æ&nbsp;¹æ®å½¢çŠ¶ç±»åž‹è®¡ç®—è¡Œå˜æ¢åæ&nbsp;‡(æžåæ&nbsp;‡)
\cs_set:Npn \__pascal_shift_row_pt:n #1
  {
    \int_case:nn { \l__pascal_shape_type_int }
      {
        {1}{
          \tl_set:Nn \l__pascal_shift_row_pt_tl { -120 \c_colon_str
              \fp_eval:n {sqrt(3) * \l__pascal_cell_radius_dim * #1}pt
            }
        }
        {2}{
          \tl_set:Nn \l__pascal_shift_row_pt_tl { -90 \c_colon_str
              \fp_eval:n {sqrt(2) * \l__pascal_cell_radius_dim * #1}pt
            }
        }
      }
  }

%% æ­£å…­è¾¹å½¢é—­åˆè·¯å¾„ä»£ç&nbsp;
\cs_set:Npn \__pascal_hex_cell:
  {
    (30  \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    (90  \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    (150 \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    (210 \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    (270 \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    (330 \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    cycle (90 \c_colon_str 0)
  }

%% æ­£æ–¹å½¢é—­åˆè·¯å¾„ä»£ç&nbsp;
\cs_set:Npn \__pascal_square_cell:
  {
    (45  \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    (134 \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    (225 \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    (-45 \c_colon_str \fp_eval:n{\l__pascal_cell_radius_dim}pt) --
    cycle (90 \c_colon_str 0)
  }

%% ç»˜åˆ¶è¡Œåˆ—ç¼–å·æ&nbsp;‡è®°å•å…ƒæ&nbsp;¼
\cs_set:Npn \__pascal_num_draw:nnn #1#2#3
  {
    \int_case:nn { \l__pascal_shape_type_int }
      {
        {1}{% æ­£å…­è¾¹å½¢
          \int_compare:nNnT { #1 } = {0}% æœ€å·¦åˆ—
            {
              \int_compare:nNnT { #2 } = { #3 - 1 }% æœ€åº•è¡Œ
                {
                  \begin{scope}[shift={(-150\c_colon_str {\fp_eval:n{3*\l__pascal_cell_radius_dim}pt})}]
                    \draw[dashed, top~color=gray!10,bottom~color=gray!20]
                      \__pascal_hex_cell:
                      node[rotate=-45] {$m,n$};
                  \end{scope}
                }
            }
          \int_compare:nNnT { #1 } = { 0 }% æœ€å·¦åˆ—
            {
              \begin{scope}[shift={(-180\c_colon_str {\fp_eval:n{sqrt(3)*\l__pascal_cell_radius_dim}pt})}]
                \draw[dashed, top~color=gray!10,bottom~color=gray!20]
                  \__pascal_hex_cell:
                  node{$(\int_eval:n {#2})$};
              \end{scope}
            }
          \int_compare:nNnT { #2 } = { #3 - 1 }% æœ€åº•è¡Œ
            {
              \begin{scope}[shift={(-120\c_colon_str {\fp_eval:n{sqrt(3)*\l__pascal_cell_radius_dim}pt})}]
                \draw[dashed, top~color=gray!10,bottom~color=gray!20]
                  \__pascal_hex_cell:
                  node {$(\int_eval:n {#1})$};
              \end{scope}
            }
        }
        {2}{% æ­£æ–¹å½¢
          \int_compare:nNnT { #1 } = {0}% æœ€å·¦åˆ—
            {
              \int_compare:nNnT { #2 } = { #3 - 1 }% æœ€åº•è¡Œ
                {
                  \begin{scope}[shift={(-135\c_colon_str {\fp_eval:n{2*\l__pascal_cell_radius_dim}pt})}]
                    \draw[dashed, top~color=gray!10,bottom~color=gray!20]
                      \__pascal_square_cell:
                      node[scale=0.8,rotate=-45] {$m,n$};
                  \end{scope}
                }
            }
          \int_compare:nNnT { #1 } = { 0 }% æœ€å·¦åˆ—
            {
              \begin{scope}[shift={(-180\c_colon_str {\fp_eval:n{sqrt(2)*\l__pascal_cell_radius_dim}pt})}]
                \draw[dashed, top~color=gray!10,bottom~color=gray!20]
                  \__pascal_square_cell:
                  node{$(\int_eval:n {#2})$};
              \end{scope}
            }
          \int_compare:nNnT { #2 } = { #3 - 1 }% æœ€åº•è¡Œ
            {
              \begin{scope}[shift={(-90\c_colon_str {\fp_eval:n{sqrt(2)*\l__pascal_cell_radius_dim}pt})}]
                \draw[dashed, top~color=gray!10,bottom~color=gray!20]
                  \__pascal_square_cell:
                  node {$(\int_eval:n {#1})$};
              \end{scope}
            }
        }
      }
  }

%% ç»˜åˆ¶ä¸‰è§’å½¢å•å…ƒæ&nbsp;¼
\cs_set:Npn \__pascal_cell_draw:nn #1#2
  {
    \int_case:nn { \l__pascal_shape_type_int }
      {
        {1}{% æ­£å…­è¾¹å½¢
          \draw[top~color=\l__pascal_cell_color_tl!20,bottom~color=\l__pascal_cell_color_tl!60]
            \__pascal_hex_cell:
            \bool_if:NTF \l__pascal_binom_cell_bool
              {
                node {$\binom{\int_eval:n {#1}}{\int_eval:n {#2}}$};
              }
              {
                node {$\__pascal_binomcoeff:nn {#1}{#2}$};
              }
        }
        {2}{% æ­£æ–¹å½¢
          \draw[top~color=\l__pascal_cell_color_tl!20,bottom~color=\l__pascal_cell_color_tl!60]
            \__pascal_square_cell:
            \bool_if:NTF \l__pascal_binom_cell_bool
              {
                node {$\binom{\int_eval:n {#1}}{\int_eval:n {#2}}$};
              }
              {
                node {$\__pascal_binomcoeff:nn {#1}{#2}$};
              }
        }
      }
  }

%% ç»˜åˆ¶Pascalä¸‰è§’å½¢
% ç­‰è…°ä¸‰è§’å½¢çš„ç»˜åˆ¶åŽŸç†å‚è€ƒäº† https://texample.net/tikz/examples/pascal-triangle/
% Author: M.H. Ahmadi
\cs_set:Npn \__pascal_triangle_draw:n #1
  {
    % è®¾ç½®æ­£å¸¸å•å…ƒæ&nbsp;¼ä¸ºç°è‰²
    \tl_set:Nn \l__pascal_cell_color_tl {gray}
    % è®°å½•ç»˜åˆ¶åˆ—æ•°
    \int_set:Nn \l_tmpa_int {#1}

    % ä½¿ç”¨TikZç»˜åˆ¶
    \begin{tikzpicture}[font=\l__pascal_font_size_tl]
      % åˆ—å¾ªçŽ¯
      \int_step_inline:nn {\l_tmpa_int}
        {
          % è°ƒæ•´ä¸ºä»Ž0è®¡æ•°ï¼Œä»¥ä¾¿äºŽåŽç»­è®¡ç®—
          \int_set:Nn \l__pascal_col_idx_int { ##1 - 1 }

          % è®¡ç®—åˆ—å˜æ¢åæ&nbsp;‡(æžåæ&nbsp;‡)
          \__pascal_shift_col_pt:n {\l__pascal_col_idx_int}

          % ç”¨scopeçŽ¯å¢ƒå˜æ¢å„åˆ—åˆ°æŒ‡å®šä½ç½®
          \begin{scope}[shift={(\l__pascal_shift_col_pt_tl)}]
            % è®¡ç®—æ¯åˆ—æœ€å¤šè¡Œæ•°
            \int_set:Nn \l__pascal_row_top_int {\l_tmpa_int - ##1 + 1}

            % è¡Œå¾ªçŽ¯
            \int_step_inline:nn { \l__pascal_row_top_int }
            {
              % è°ƒæ•´ä¸ºä»Ž0è®¡æ•°ï¼Œä»¥ä¾¿äºŽåŽç»­è®¡ç®—
              \int_set:Nn \l__pascal_row_idx_int { ####1 - 1 }

              % è®¡ç®—ç»„åˆæ•°è®¡ç®—ä¸­çš„è¡Œæ•°
              \int_zero:N \l__pascal_total_idx_int
              \int_add:Nn \l__pascal_total_idx_int { \l__pascal_row_idx_int }
              \int_add:Nn \l__pascal_total_idx_int { \l__pascal_col_idx_int }

              % ä¸ºæŒ‡å®šè¡Œè®¾ç½®ç»˜åˆ¶é¢œè‰²
              \int_case:nn { \l__pascal_col_idx_int }
                {
                  {0}{
                    \tl_set:Nn \l__pascal_cell_color_tl { pink }
                  }
                  {1}{
                    \tl_set:Nn \l__pascal_cell_color_tl { yellow }
                  }
                  {2}{
                    \tl_set:Nn \l__pascal_cell_color_tl { blue }
                  }
                  {3}{
                    \tl_set:Nn \l__pascal_cell_color_tl { green }
                  }
                  {\l__pascal_fill_col_int - 1}{
                    \int_compare:nNnTF{\l__pascal_row_idx_int} &lt; { \l__pascal_fill_row_int + 1 }
                      {\tl_set:Nn \l__pascal_cell_color_tl { purple }}
                      {\tl_set:Nn \l__pascal_cell_color_tl { gray }}
                  }
                  {\l__pascal_fill_col_int}{
                    \int_compare:nNnTF{\l__pascal_row_idx_int} = { \l__pascal_fill_row_int }
                      {\tl_set:Nn \l__pascal_cell_color_tl { purple }}
                      {\tl_set:Nn \l__pascal_cell_color_tl { gray }}
                  }
                }

              % è®¡ç®—è¡Œå˜æ¢åæ&nbsp;‡(æžåæ&nbsp;‡)
              \__pascal_shift_row_pt:n {\l__pascal_row_idx_int}
              % ç”¨scopeçŽ¯å¢ƒå˜æ¢å„è¡Œåˆ°æŒ‡å®šä½ç½®
              \begin{scope}[shift={(\l__pascal_shift_row_pt_tl)}]
                % æ˜¯å¦ç»˜åˆ¶è¡Œåˆ—ç¼–å·
                \bool_if:NT \l__pascal_num_cell_bool
                  {
                    \__pascal_num_draw:nnn { \l__pascal_col_idx_int }
                                           { \l__pascal_row_idx_int }
                                           { \l__pascal_row_top_int }
                  }
                % ç»˜åˆ¶ä¸€ä¸ªå•å…ƒæ&nbsp;¼
                \__pascal_cell_draw:nn{\l__pascal_total_idx_int}{\l__pascal_col_idx_int}
              \end{scope}
            }
          \end{scope}
        }
    \end{tikzpicture}
  }

%% ç»˜åˆ¶Pascalä¸‰è§’å½¢ç”¨æˆ·æŽ¥å£
\NewDocumentCommand{\pascal}{O{} m}
  {
    \group_begin:
      \keys_set:nn { pascal } {#1}
      \__pascal_triangle_draw:n{#2}
    \group_end:
  }

\endinput
</pre></body></html>