tud-cd / tudscr

TUD-Script
Other
105 stars 22 forks source link

package for list of symbols via `glossaries` with (semi-)automatic split und sorting #90

Open mrpiggi opened 8 months ago

mrpiggi commented 8 months ago

First draft

\RequirePackage{booktabs,tabu,longtable}
\PassOptionsToPackage{acronym,symbols}{glossaries}

\AfterPackage*{glossaries}{%
  \newglossarystyle{acrotabu}{%
    \renewenvironment{theglossary}{%
%      \begin{tabu}spread 0pt{@{}lX<{\strut}l@{}}% mit Seitenangabe
      \begin{tabu}{@{}lX<{\strut}@{}}% ohne Seitenangabe
    }{%
      \end{tabu}\par\bigskip%
    }%
    \renewcommand*{\glossaryheader}{}%
    \renewcommand*{\glsgroupheading}[1]{}%
    \renewcommand*{\glsgroupskip}{}%
    \renewcommand*{\glossentry}[2]{%
      \glsentryitem{##1}% Entry number if required
      \glstarget{##1}{\sffamily\bfseries\glossentryname{##1}} &
      \glsentrydesc{##1}%
%      & ##2% mit Seitenangabe
      \tabularnewline%
    }
  }
  \newcommand*\symbollettergroup{}
  \newcommand*{\newformulasymbol}[5][]{%
    \ifisgreeksymbol{#4}{%
      \renewcommand*{\symbollettergroup}{greekletters}%
    }{%
      \renewcommand*{\symbollettergroup}{romanletters}%
    }%
    \newglossaryentry{#2}{%
      type=symbols,%
      name={#3},%
      description={\nopostdesc},%
      symbol={\ensuremath{#4}},%
      user1={\ensuremath{\mathrm{#5}}},%
      sort={#2},%
      parent={\symbollettergroup},%
      #1%
    }%
  }
  \defglsentryfmt[symbols]{%
    \ifmmode%
      \glssymbol{\glslabel}%
    \else%
      \glsgenentryfmt~\glsentrysymbol{\glslabel}%
    \fi%
  }
  \providecommand*\greeklettersname{Greek letters}
  \providecommand*\romanlettersname{Roman letters}
  \providecaptionname{%
    american,australian,british,canadian,english,newzealand%
  }{\greeklettersname}{Greek letters}
  \providecaptionname{%
    german,ngerman,austrian,naustrian,swissgerman,nswissgerman%
  }{\greeklettersname}{Griechische Symbole}
  \providecaptionname{%
    american,australian,british,canadian,english,newzealand%
  }{\romanlettersname}{Roman letters}
  \providecaptionname{%
    german,ngerman,austrian,naustrian,swissgerman,nswissgerman%
  }{\romanlettersname}{Lateinische Symbole}
  \newglossaryentry{greekletters}{%
    type=symbols,%
    name={\greeklettersname},%
    description={\nopostdesc},%
    sort={a}%
  }
  \newglossaryentry{romanletters}{%
    type=symbols,%
    name={\romanlettersname},%
    description={\nopostdesc},%
    sort={b}%
  }

  \newglossarystyle{symbsplitlongtabu}{%
    \newcommand*\symbollevel{-1}%
    \renewenvironment{theglossary}{%
%      \begin{longtabu}spread 0pt[l]{ccX<{\strut}l}% mit Seitenangabe
      \begin{longtabu}[l]{ccX<{\strut}}% ohne Seitenangabe
    }{%
      \end{longtabu}%
    }%
    \renewcommand*{\glsgroupheading}[1]{}%
    \renewcommand*{\glsgroupskip}{}%
    \newcommand*\symbolhead{%
      \toprule
      \bfseries Formelzeichen & \bfseries Einheit &
      \bfseries Bezeichnung %& \bfseries Seite(n)
      \tabularnewline\midrule
    }%
    \renewcommand*{\glossaryheader}{%
      \endfirsthead%
      \symbolhead\endhead%
      \bottomrule\endfoot%
      \gdef\symbollevel{-1}%
    }%
    \renewcommand*{\glossentry}[2]{%
      \ifglshaschildren{##1}{%
        \ifnum\symbollevel>0\relax%
          \tabularnewline\bottomrule\tabularnewline[\smallskipamount]%
        \fi
        \gdef\symbollevel{0}%
        \tabularnewline[%
          \arraystretch\dimexpr-\ht\strutbox-\dp\strutbox\relax%
        ]%
%        \multicolumn{4}{@{}l@{}}{\minisec{\glsentryname{##1}}}%mit Seitenangabe
        \multicolumn{3}{@{}l@{}}{\minisec{\glsentryname{##1}}}%ohne Seitenangabe
      }{%
        \GlossariesWarning{%
          There are no childrens for entry ##1.\MessageBreak
          Nothing will be printed. Maybe you should\MessageBreak
          specify ##1 as a child entry.
        }%
      }%
    }%
    \renewcommand*{\subglossentry}[3]{%
      \ifnum\symbollevel=0\relax%
        \tabularnewline[\medskipamount]\symbolhead%
      \else%
        \tabularnewline
      \fi%
      \gdef\symbollevel{##1}%
      \glsentryitem{##2}% Entry number if required
      \glstarget{##2}{\glossentrysymbol{##2}} &
      \glsentryuseri{##2} &
      \glossentryname{##2}%
      %& ##3% mit Seitenangabe
    }%
  }
  }% Ende von AfterPackage
  \makeatletter
  \newcommand*\greeksymbollist{}
  \def\@tempa#1{\ifdefvoid{#1}{}{\listadd\greeksymbollist{#1}}}
  \forcsvlist{\@tempa}{%
    \alpha,\beta,\varbeta,\gamma,\delta,\epsilon,\varepsilon,\zeta,%
    \eta,\theta,\vartheta,\iota,\kappa,\varkappa,\lambda,\mu,\nu,%
    \xi,\omicron,\pi,\varpi,\rho,\varrho,\sigma,\varsigma,\tau,%
    \upsilon,\phi,\varphi,\chi,\psi,\omega,%
    \Alpha,\Beta,\Gamma,\Delta,\Epsilon,\Zeta,\Eta,\Theta,\Iota,%
    \Kappa,\Lambda,\Mu,\Nu,\Xi,\Omicron,\Pi,\Rho,\Sigma,\Tau,\Upsilon,%
    \Phi,\Chi,\Psi,\Omega%
  }
  \newcommand*\ifisgreeksymbol[1]{%
    \begingroup%
      \def\@tempa##1{\let##1\@firstofone}%
      \forcsvlist{\@tempa}{%
        \acute,\bar,\breve,\check,\dot,\ddot,\dddot,\ddddot,%
        \hat,\widehat,\grave,\tilde,\widetilde,\vec,%
        \Acute,\Bar,\Breve,\Check,\Dot,\Ddot,\Hat,\Grave,\Tilde,\Vec%
      }%
      \def\boldsymbol{}%
      \protected@edef\@tempa{#1}%
      \def\@tempb##1_##2\relax{\def\@tempa{##1}}%
      \expandafter\@tempb\@tempa_\relax\relax%
      \def\@tempb##1^##2\relax{\def\@tempa{##1}}%
      \expandafter\@tempb\@tempa^\relax\relax%
      \expandafter\ifinlist\expandafter{\@tempa}{\greeksymbollist}{%
        \aftergroup\@firstoftwo%
      }{%
        \aftergroup\@secondoftwo%
      }%
    \endgroup%
  }
\makeatother
mrpiggi commented 8 months ago

Evolved draft:

```latex
\documentclass[english,ngerman,cdfont=false]{tudscrreprt}
\usepackage{iftex}
\iftutex
  \usepackage{fontspec}
\else
  \usepackage[T1]{fontenc}
  \usepackage[ngerman=ngerman-x-latest]{hyphsubst}
\fi
\usepackage{babel}
\usepackage{xltabular}
\usepackage{booktabs}
\usepackage{siunitx}
\usepackage{lmodern}

\AfterPackage*{hyperref}{%
\usepackage[%
%  acronym,% Abkürzungen
  symbols,% Formelzeichen
  nomain,% kein Glossar
  nogroupskip,%
  toc,%
  section=chapter,%
  nostyles,%
  translate=babel,%
% mit Tex Live einfach verwendbar
  xindy={language=german-din},
]{glossaries}
\makeglossaries
}% Ende von AfterPackage

\makeatletter
\newcommand*\glssort@roman{%
  a,A,b,B,c,C,d,D,e,E,f,F,g,G,h,H,i,I,j,J,k,K,l,L,m,M,
  n,N,o,O,p,P,q,Q,r,R,s,S,t,T,u,U,v,V,w,W,x,X,y,Y,z,Z%
}
\newcommand*\glssort@greek{%
  \alpha,\Alpha,\beta,\varbeta,\Beta,\gamma,\Gamma,\delta,\Delta,%
  \epsilon,\varepsilon,\Epsilon,\zeta,\Zeta,\eta,\Eta,\theta,\vartheta,\Theta,%
  \iota,\Iota,\kappa,\varkappa,\Kappa,\lambda,\Lambda,\mu,\Mu,\nu,\Nu,\xi,\Xi,%
  \omicron,\Omicron,\pi,\varpi,\Pi,\rho,\varrho,\Rho,\sigma,\varsigma,\Sigma,%
  \tau,\Tau,\upsilon,\Upsilon,\phi,\varphi,\Phi,\chi,\Chi,\psi,\Psi,%
  \omega,\varomega,\Omega%
}
\newcommand*\diff[1]{\upDelta#1}
\newcommand*\glssort@accent{%
  \diff,\acute,\bar,\breve,\check,\dot,\ddot,\dddot,\ddddot,%
  \hat,\widehat,\grave,\tilde,\widetilde,\vec,\mathring,%
  \Acute,\Bar,\Breve,\Check,\Dot,\Ddot,\Hat,\Grave,\Tilde,\Vec%
}
\newcommand*\glssort@index[5]{%
  \begingroup%
    \glssort@sanitize\@tempa{#2}%
    % erster Token für Vergleich
    \def\@tempc##1##2\@nil{\def\@tempb{##1}}%
    \expandafter\@tempc\@tempa\@nil%
    \@tempswafalse%
    \@tempcnta=0%
    % Schleife für Token-Vergleich aus Listen \glssort@roman und \glssort@greek
    \def\do##1{%
      \if@tempswa\else%
        \def\@tempc{##1}%
        \ifx\@tempb\@tempc\@tempswatrue\fi%
        \if@tempswa\else\advance\@tempcnta\@ne\fi%
      \fi%
    }%
    \edef\@tempc{\expandonce\glssort@roman,\expandonce\glssort@greek}%
    \expandafter\docsvlist\expandafter{\@tempc}%
    \edef\@tempa{%
      \unexpanded{\edef\@tempa}{%
        \noexpand\zap@space\detokenize\expandafter{\@tempa}%
        \space\noexpand\@empty%
      }%
    }%
    \@tempa%
    \edef\@tempa{%
      \endgroup%
      \unexpanded{\def#1}{%
        \ifnum\@tempcnta<100 0\fi\ifnum\@tempcnta<10 0\fi\the\@tempcnta%
        \space\@tempa\space<#3>%
      }%
    }%
  \@tempa%
  \typeout{====== sort index: `#1' - #5}%
  \typeout{\@spaces\@spaces\@spaces input: `\detokenize{#2}' - \detokenize{#4}}%
}
\AfterPackage*{glossaries}{%
  \newcommand*\symbollettergroup{}
  \newcommand*\newformulasymbol[5][]{%
    \ifisgreeksymbol{#4}{%
      \renewcommand*{\symbollettergroup}{greekletters}%
    }{%
      \renewcommand*{\symbollettergroup}{romanletters}%
    }%
    \begingroup%
      \let\@tempb\@empty%
      \let\@tempc\@empty%
      % zusätzlicher Key 'sortsymbol' wird hier herausgefiltert, Wert in \@tempc
      % restliche optionale Argumente werden in \@tempb gesichert
      \def\@tempa##1,sortsymbol=##2,##3\@nil{%
        \IfArgIsEmpty{##1}{}{\appto\@tempb{##1}}%
        \IfArgIsEmpty{##2}{}{\def\@tempc{##2}}%
        \IfArgIsEmpty{##3}{}{\@tempa,##3\@nil}%
      }%
      \@tempa,#1,sortsymbol=,\@nil%
      \def\@tempa{%
        type=symbols,%
        parent={\symbollettergroup},%
        name={#3},%
        description={\nopostdesc},%
        symbol={\ensuremath{#4}},%
        user1={\si{#5}}%
      }%
      \eappto\@tempa{\expandonce\@tempb}%
      \ifx\@tempc\@empty%
        \glssort@index\@tempb{#4}{#2}{#3}{default key and label}%
      \else%
        \def\@tempb##1|##2|##3\@nil{%
          \IfArgIsEmpty{##3}{%
            \glssort@index\@tempb{#4}{##1}{#3}{default key, custom label}%
          }{%
            \IfArgIsEmpty{##2}{%
              \glssort@index\@tempb{##1}{#2}{#3}{custom key, default label}%
            }{%
              \glssort@index\@tempb{##1}{##2}{#3}{custom key and label}%
            }%
          }%
        }%
        \expandafter\@tempb\@tempc||\@nil%
      \fi%
      \epreto\@tempa{sort={\@tempb},}%
      \edef\@tempb{%
        \endgroup%
        \unexpanded{\newglossaryentry{#2}}{\expandonce\@tempa}%
      }%
    \@tempb%
  }%
  \defglsentryfmt[symbols]{%
    \ifmmode%
      \glssymbol{\glslabel}%
    \else%
      \glsgenentryfmt~\glsentrysymbol{\glslabel}%
    \fi%
  }
  \providecommand*\greeklettersname{Greek letters}
  \providecommand*\romanlettersname{Roman letters}
  \newglossaryentry{greekletters}{%
    type=symbols,%
    name={\greeklettersname},%
    description={\nopostdesc},%
    sort={a}%
  }
  \newglossaryentry{romanletters}{%
    type=symbols,%
    name={\romanlettersname},%
    description={\nopostdesc},%
    sort={b}%
  }
  \newglossarystyle{symbxltab}{%
    \newcommand*\symbollevel{-1}%
    \renewenvironment{theglossary}{%
      \xltabular[l]{\linewidth}{ccXl}%
    }{%
      \endxltabular%
    }%
    \renewcommand*{\glsgroupheading}[1]{}%
    \renewcommand*{\glsgroupskip}{}%
    \newcommand*\symbolhead{%
      \toprule
      \bfseries Formelzeichen & \bfseries Einheit &
      \bfseries Bezeichnung %& \bfseries Seite(n)
      \tabularnewline\midrule
    }%
    \renewcommand*{\glossaryheader}{%
      \endfirsthead%
      \symbolhead\endhead%
      \bottomrule\endfoot%
      \gdef\symbollevel{-1}%
    }%
    \renewcommand*{\glossentry}[2]{%
      \ifglshaschildren{##1}{%
        \ifnum\symbollevel>0\relax%
          \tabularnewline\bottomrule\tabularnewline[\smallskipamount]%
        \fi
        \gdef\symbollevel{0}%
        \tabularnewline[%
          \arraystretch\dimexpr-\ht\strutbox-\dp\strutbox\relax%
        ]%
%        \multicolumn{4}{@{}l@{}}{\minisec{\glsentryname{##1}}}%mit Seitenangabe
        \multicolumn{3}{@{}l@{}}{\minisec{\glsentryname{##1}}}%ohne Seitenangabe
      }{%
        \GlossariesWarning{%
          There are no childrens for entry ##1.\MessageBreak
          Nothing will be printed. Maybe you should\MessageBreak
          specify ##1 as a child entry.
        }%
      }%
    }%
    \renewcommand*{\subglossentry}[3]{%
      \ifnum\symbollevel=0\relax%
        \tabularnewline[\medskipamount]\symbolhead%
      \else%
        \tabularnewline
      \fi%
      \gdef\symbollevel{##1}%
      \glsentryitem{##2}% Entry number if required
      \glstarget{##2}{\glossentrysymbol{##2}} &
      \glsentryuseri{##2} &
      \glossentryname{##2}%
      %& ##3% mit Seitenangabe
    }%
  }
}% Ende von AfterPackage
\newcommand*\mushift[1]{\mkern#1mu}
\newcommand*\barshift[2]{\bar{#1\mushift{#2}}\mushift{-#2}}
\newcommand*\glssort@sanitize[2]{%
  \begingroup%
    \def\do##1{\let##1\@firstofone}%
    \expandafter\docsvlist\expandafter{\glssort@accent}%
    \let\boldsymbol\relax%
    \let\mathrm\@firstofone%
    \let\mushift\@gobble%
    \protected@edef\@tempa{\endgroup\unexpanded{\def#1}{#2}}%
  \@tempa%
}
\newcommand*\ifisgreeksymbol[1]{%
  \begingroup%
    \glssort@sanitize\@tempa{#1}%
    \def\@tempb##1##2\@nil{\def\@tempa{##1}}%
    \expandafter\@tempb\@tempa\@nil%
    \edef\@tempb{%
      \noexpand\in@{,\expandonce\@tempa,}{,\expandonce\glssort@greek,}%
    }%
    \@tempb%
    \ifin@
      \aftergroup\@firstoftwo%
    \else%
      \aftergroup\@secondoftwo%
    \fi%
  \endgroup%
}
\makeatother
\usepackage[colorlinks]{hyperref}

\AtBeginDocument{
\newformulasymbol{u}{Test}{u}{}
\newformulasymbol{U}{Spannung}{U}{\V}
\newformulasymbol{dUold}{Spannungshub (alt)}{\diff{U}}{\V}
\newformulasymbol[sortsymbol=Udiff]{dU}{Spannungshub (neu)}{\diff{U}}{\V}
\newformulasymbol[sortsymbol=U_0|Udiff]{cU}{Spannungshub (custom)}{\diff{U}}{\V}
\newformulasymbol{U0}{Ruhespannung}{U_0}{\V}
\newformulasymbol{Ud}{Zwischenkreisspannung}{U_\mathrm{d}}{\V}
\newformulasymbol{U0av}{mittlere Ruhespannung}{\bar{U_0}}{\V}

}
\begin{document}

\gls{u}
\gls{U}
\gls{U0}
\gls{Ud}
\gls{U0av}
\gls{dUold}
\gls{dU}
\gls{cU}

\printsymbols[style=symbxltab]

\end{document}