Archive for the ‘Tipps & Tricks’ Category.

Arara Regel, um alle Asymptote Dateien zu übersetzen

Mit der Hilfe von Claude Opus habe ich eine Regel für Arara geschrieben, die alle asy Dateien im LaTeX-Verzeichnis übersetzt. Auf meinem Rechner liegt die Datei dann als arara-rule-asymptoteall.yaml in C:\texlive\2026\texmf-dist\scripts\arara\rules, unten ein Beispiel für den Aufruf.

!config
identifier: AsymptoteAll
name: AsymptoteAll
authors:
- Uwe Ziegenhagen, ziegenhagen@gmail.com
commands:
- name: Asymptote all *.asy files in directory
  command: >
    @{
      directory = new java.io.File(reference.toString())
                      .getAbsoluteFile().getParentFile();
      commands = [];
      foreach (file : directory.listFiles()) {
        if (file.getName().endsWith('.asy')) {
          commands.add(getCommandWithWorkingDirectory(
            directory.getAbsolutePath(),
            'asy', '-f', format, file.getName()));
        }
      }
      if (commands.isEmpty()) {
        throwError('No .asy-files found in ' + reference.toString());
      }
      return commands;
    }
arguments:
- identifier: format
  flag: >
    @{
      return parameters.format;
    }
  default: 'pdf'

Verbesserungspotential gibt es noch, die Parameterübergabe ist noch nicht für mehrere Parameter angepasst, auch werden bei jedem Arara-Lauf alle Dateien — auch die unveränderten — neu übersetzt.

%!TEX TS-program = Arara
% arara: pdflatex: { shell: yes }
% arara: AsymptoteAll
% arara: pdflatex: { shell: yes }
 
\documentclass{article}
\usepackage[inline]{asymptote}
 
% Definitionen, die alle asy-Bilder im Dokument sehen sollen:
\begin{asydef}
import geometry;
defaultpen(fontsize(10pt));
\end{asydef}
 
\newcommand{\vek}[1]{\mathbf{#1}}
 
\begin{document}
 
Der Einheitskreis mit eingezeichnetem Radius:
 
\begin{center}
\begin{asy}
size(5cm);
draw(unitcircle, blue+0.8bp);
pair M = (0,0), P = dir(35);
draw(M--P, red, Arrow(4));
dot(M); dot(P);
label("$M$", M, SW);
label("$P$", P, NE);
label("$\vek{r}$", midpoint(M--P), NW);
\end{asy}
\end{center}
 
 
\begin{center}
\begin{asy}
size(5cm);
draw(unitcircle, blue+0.8bp);
pair M = (0,0), P = dir(35);
draw(M--P, red, Arrow(4));
dot(M); dot(P);
label("$M$", M, SW);
label("$P$", P, NE);
label("$\vek{r}$", midpoint(M--P), NW);
\end{asy}
\end{center}
\end{document}

PDF Dateien pixelbasiert miteinander vergleichen

Ausgehend von einer Anfrage auf der Dante Beraterkreis Mailingliste hier einige Ideen, wie man pixelbasiert PDF-Dateien miteinander vergleichen kann.

Schritt 1: Umwandlung ins PNG Format. Ich nutze dazu pdftoppm aus dem Poppler-Paket.


pdftoppm -png 1.pdf > 1.png

das gleiche dann nochmal für die zweite Datei.

Dann mit ein wenig Python-Magie die beiden PNGs vergleichen:

 
from PIL import Image, ImageChops # generic
import numpy as np # numerical
from skimage.metrics import structural_similarity as ssim
import cv2
 
# Load the images
img1 = Image.open("1.png")
img2 = Image.open("2.png")
 
# Compute absolute difference
diff = ImageChops.difference(img1, img2)
 
# Save or show the difference image
diff.save("difference.png")
diff.show()
 
 
# Load PNGs into numpy arrays
img1 = np.array(Image.open("1.png"))
img2 = np.array(Image.open("2.png"))
 
# Compute pixel-wise absolute difference
diff = np.abs(img1.astype(int) - img2.astype(int))
 
# Save result
Image.fromarray(diff.astype(np.uint8)).save("difference.png")
# Or compute some stats:
print("Mean difference:", diff.mean())
print("Max difference:", diff.max())
 
 
# Convert to grayscale
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
 
score, diff = ssim(gray1, gray2, full=True)
print("SSIM:", score)
 
# diff is in [0,1]; scale to 0-255 to view as an image
diff = (diff * 255).astype("uint8")
cv2.imwrite("ssim_diff.png", diff)

Behringer Abacus / Mutuable Instruments Maths in TikZ

Hier ein Versuch, ein Maths bzw. Abacus Eurorack Modul mit TikZ zu zeichnen.

%!TEX TS-program = pdflatex
\documentclass[12pt,ngerman,tikz]{standalone}
 
\begin{document}
\begin{tikzpicture}[red,draw=red, fill=red]
 
% a plug
\newcommand{\plug}[2]{% three circles, inner one is filled
    \fill (#1,#2) circle (0.1875cm);
    \draw (#1,#2) circle (0.28cm);
    \draw (#1,#2) circle (0.42cm);
}
 
% buttons
\newcommand{\button}[2]{% three circles, inner one is filled
    \fill (#1,#2) circle (0.5cm);
    \fill[white] (#1,#2) circle (0.4cm);
}
 
% a plug with a label above
\newcommand{\labelplug}[3]{%
    \fill (#1,#2) circle (0.1875cm);
    \draw (#1,#2) circle (0.28cm);
    \draw (#1,#2) circle (0.42cm);
    \node[above=0.35cm,font=\sffamily\bfseries\scriptsize] at (#1,+#2) {#3};
}
 
%  \knob{x}{y}{size}{angle} 
\newcommand{\knob}[4]{%
  \pgfmathsetmacro{\radius}{#3}%
  \pgfmathsetmacro{\reduced}{\radius * 0.8}%
  \pgfmathsetmacro{\tikzAngle}{90 - #4}%
  \draw[thick, fill=white!30] (#1,#2) circle (\radius cm);
  \draw[line width=2pt, red] (#1,#2) -- ++(\tikzAngle:\reduced cm);
}
 
% plug with label and led, in a frame
\newcommand{\labelplugled}[3]{%
    \fill (#1,#2) circle (0.1875cm);
    \draw (#1,#2) circle (0.28cm);
    \draw (#1,#2) circle (0.42cm);
    \node[above=0.35cm,font=\sffamily\bfseries\scriptsize] at (#1,#2) {#3};
     \draw[rounded corners=2pt]
      (#1-0.5, #2-0.5)
        rectangle
      (#1+0.5, {#2+1.2});
    \draw (#1,#2+0.945) circle (0.1cm);
}
 
% plug with label but no led, in a frame
\newcommand{\labelplugnoled}[3]{%
    \fill (#1,#2) circle (0.1875cm);
    \draw (#1,#2) circle (0.28cm);
    \draw (#1,#2) circle (0.42cm);
    \node[above=0.35cm,font=\sffamily\bfseries\scriptsize] at (#1,#2) {#3};
     \draw[rounded corners=2pt]
      (#1-0.5, #2-0.5)
        rectangle
      (#1+0.5, {#2+1.2});
 
}
 
% Screenshot from the manual, in the background
%\node[anchor=north west ,inner sep=0] (frame1) at (1,13)    {\includegraphics[width=10cm]{2025-09-20 04 09 06.png}};
 
% grid
\draw[help lines,red] (0,0) grid (13,14);
 
\draw[very thick, rounded corners=2pt](1,0.35) rectangle (11,13);
 
\labelplug{1.75}{11.5}{IN 1};
\labelplug{2.85}{11.5}{TRIG 1};
 
\labelplug{5.45}{11.5}{IN 2};
\labelplug{6.55}{11.5}{IN 3};
 
\labelplug{9.175}{11.5}{TRIG 4};
\labelplug{10.25}{11.5}{IN 4};
 
\plug{1.75}{10.2};
\plug{1.75}{9};
\plug{1.75}{7.9};
\plug{1.75}{6.55};
 
\plug{10.25}{10.2};
\plug{10.25}{9};
\plug{10.25}{7.9};
\plug{10.25}{6.55};
 
 
\labelplugled{1.75}{1.8}{EOR};
\labelplugled{2.9}{1.8}{$\smallint$};
 
\labelplugnoled{4.9}{1.8}{OR};
\labelplugled{6}{1.8}{SUM};
\labelplugnoled{7.1}{1.8}{INV};
 
\labelplugled{9.14}{1.8}{$\smallint$};
\labelplugled{10.25}{1.8}{EOC};
 
\labelplugnoled{4.25}{3.6}{OUT 1};
\labelplugnoled{5.4}{3.6}{OUT 2};
\labelplugnoled{6.55}{3.6}{OUT 3};
\labelplugnoled{7.7}{3.6}{OUT 4};
 
\knob{3.5}{10.2}{0.7}{0}
\knob{8.5}{10.2}{0.7}{0}
 
\knob{3.5}{7.9}{0.7}{0}
\knob{8.5}{7.9}{0.7}{0}
 
\knob{3.5}{5.7}{0.7}{0}
\knob{8.5}{5.7}{0.7}{0}
 
\knob{5}{9}{0.35}{0}
\knob{7}{9}{0.35}{0}
\knob{5}{6.75}{0.35}{0}
\knob{7}{6.75}{0.35}{0}
 
\button{2.3}{4.15}
\button{9.7}{4.15}
 
\node at (5,9.6){\sffamily\bfseries\footnotesize1};
\node at (7,9.6){\sffamily\bfseries\footnotesize4};
\node at (5,7.35){\sffamily\bfseries\footnotesize2};
\node at (7,7.35){\sffamily\bfseries\footnotesize4};
 
\node at (4.75,8.5){\sffamily\bfseries--};
\node at (5.3,8.5){\sffamily\bfseries+};
\node at (4.75,6.25){\sffamily\bfseries--};
\node at (5.3,6.25){\sffamily\bfseries+};
 
\node at (6.75,8.5){\sffamily\bfseries--};
\node at (7.3,8.5){\sffamily\bfseries+};
\node at (6.75,6.25){\sffamily\bfseries--};
\node at (7.3,6.25){\sffamily\bfseries+};
 
 
\draw[very thick] (3.4,11.5) -- (3.95,11.5) -- (5,10.5) -- (5,9.8);
\draw[very thick] (8.7,11.5) -- (8.1,11.5) -- (7,10.5) -- (7,9.8);
 
\draw[very thick] (5.45,10.85) -- (5.7,10.6) -- (5.7,7.5) -- (5.3,7.1);
\draw[very thick] (6.55,10.85) -- (6.3,10.6) -- (6.3,7.5) -- (6.7,7.1);
 
\foreach \x in {0,1,2,3,4,5,6,7,8,9,10,11,12} {
\node(a) at (\x,-0.5){\x};}
 
\foreach \y in {0,1,2,3,4,5,6,7,8,9,10,11,12,13} {
\node(a) at (0.5,\y){\y};}
 
\end{tikzpicture}
\end{document}

abacus_tikz

Drumpatterns mit TikZ zeichnen

Hier ein wenig TikZ-Code, um Drumpatterns für einen Drumcomputer mit TikZ zu zeichnen. Das Beispiel ist für eine Spur, es lassen sich aber beliebig viele Spuren untereinandersetzen.

%!TEX TS-program = Arara
% arara: lualatex: {shell: no}
\documentclass{scrartcl}
\usepackage[margin=1cm]{geometry}
\usepackage{tikz}
 
\begin{document}
 
\begin{tikzpicture}
    % Define the pattern as a comma-separated list
    \def\pattern{x,-,x,x,-,x,x,-,-,-,x,x,-,-,-,x}
    \def\cellsizex{1cm}
    \def\cellsizey{0.5cm}
 
    %\draw (0,0) rectangle ++ (\cellsizex-1, \cellsizey);
    \node[draw, rectangle,minimum width = \cellsizex, align=left,minimum height=\cellsizey] (a) at (\cellsizex/2,\cellsizey/2){1}; 
 
    % Loop through each character in the pattern
    \foreach \cell [count=\index from 1] in \pattern {
        % If 'x' fill the cell, otherwise leave it empty
        \if\cell x
            \fill[gray,draw=black] ({\index*\cellsizex}, 0) rectangle ++(\cellsizex, \cellsizey);
        \else
            \draw ({\index*\cellsizex}, 0) rectangle ++(\cellsizex, \cellsizey);
        \fi
    }
\end{tikzpicture}
 
\end{document}

drumbrute_pattern2.pdf

„Unscharfe“ Kreise mit TikZ

Ausgehend von einer Frage im LaTeX Reddit-Forum hier die Antwort, wie man mit Tikz „unscharfe“ Kreise zeichnen kann.

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage{tikz}
 
\begin{document}
 
\begin{tikzpicture}
\shade[inner color = gray, outer color = white] (0,0) circle [radius = 1];
\end{tikzpicture}
 
\end{document}

Drum Patterns mit LaTeX

Hier ein erster Entwurf, wie man mit LaTeX Drum Patters setzen kann.

\documentclass[12pt,ngerman]{scrartcl}
\usepackage[margin=1cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{tikz}
 
\begin{document}
 
\begin{tikzpicture}
    % Define the pattern as a comma-separated list
    \def\pattern{x,-,-,-,-,x,x,-,-,-,x,x,-,-,-,x}
    \def\cellsizex{1cm}
    \def\cellsizey{0.5cm}
 
    \node[draw, rectangle,minimum width = \cellsizex, align=left,minimum height=\cellsizey] (a) at (\cellsizex/2,\cellsizey/2){\tiny 1}; 
 
    % Loop through each character in the pattern
    \foreach \cell [count=\index from 1] in \pattern {
        % If 'x' fill the cell, otherwise leave it empty
        \if\cell x
            \fill[gray,draw=black] ({\index*\cellsizex}, 0) rectangle ++(\cellsizex, \cellsizey);
        \else
            \draw ({\index*\cellsizex}, 0) rectangle ++(\cellsizex, \cellsizey);
        \fi
    }
\end{tikzpicture}

drumbrute_pattern

ADSR Hüllkurve mit TikZ

Hier die Darstellung einer ADSR Hüllkurve (Quelle: Wikipedia) mit TikZ:

\begin{tikzpicture}
%\draw[step=0.5cm,lightgray,thin] (0,0) grid (10,7);
\draw[very thick, black,->](1,1) -- (9.5,1);
\draw[very thick, black,->](1,1) -- (1,6.5);
\draw[very thick, green,](3,1) -- (3,6);
\draw[very thick, orange,](5,1) -- (5,6);
\draw[very thick, black](7,1) -- (7,6);
\draw[very thick, magenta](9,1) -- (9,6);
 
\draw[very thick, gray,](1,1) -- (3,5.5) -- (5,4) -- (7,4)--(9,1);
% max amp line
\draw[thick, gray,dotted](0.8,5.5) -- (9.5,5.5);
 
\draw[very thick, blue,->](6,1.1) -- (6,3.9);
 
\draw[very thick, green,->](1.1,5.65) -- (2.9,5.65);
\draw[very thick, orange,->](3.1,5.65) -- (4.9,5.65);
 
\draw[very thick, blue](5.1,4) -- (6.9,4);
 
\draw[very thick, magenta,->](7.1,5.65) -- (8.9,5.65);
 
\node[label=left:0] (A) at (1,1) {};
\node[label=below:t] (B) at (9.5,1) {};
\node[label=left:{{\scriptsize Amp\textsubscript{max}}}] (C) at (1,5.5) {};
 
\node[label=above:A] (D) at (2,5.5) {};
\node[label=above:D] (E) at (4,5.5) {};
\node[label=left:S] (F) at (6,2.5) {};
\node[label=above:R] (G) at (8,5.5) {};
 
\draw[very thick, black,->](1,0.5) -- (1,0.9);
\draw[very thick, black,->](7,0.5) -- (7,0.9);
 
\node[label=above:{Key press}] (D) at (1.1,-0.2) {};
\node[label=above:{Key release}] (D) at (7.2,-0.2) {};
 
\end{tikzpicture}

TexLive Mirror setzen

So setzt man den TeX Live mirror auf einen der zentralen Server:

tlmgr option repository http://mirror.ctan.org/systems/texlive/tlnet

LaTeX Briefe mit KOMA-Script und dem scrletter Paket

Neben der Nutzung der scrlttr2 Klasse gibt es in aktuelleren KOMA-Script Versionen auch die Möglichkeit, das scrletter-Paket zu nutzen. Hier ein Beispiel:

\documentclass[12pt,ngerman]{scrartcl}
 
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{booktabs}
\usepackage{babel}
\usepackage{graphicx}
\usepackage{csquotes}
\usepackage{paralist}
\usepackage{xcolor}
\usepackage{palatino}
\usepackage{blindtext}
\usepackage{scrletter}
 
\setkomavar{fromname}{Max Mustermann}
\setkomavar{fromemail}{Max@Mustermann.de}
 
\setkomavar{fromaddress}{Musterweg 221, 12345 Musterstadt}
 
\setkomavar{firstfoot}{\usekomavar{fromemail}}
 
 
\begin{document}
\begin{letter}{Maria Mustermann \\ Mustergasse 1 \\ 12346 Musterstadt}
 
\opening{Hallo Maria,}
 
\blindtext[2]
 
\closing{Mit freundlichen Grüßen}
 
\end{letter}
\end{document}

Nützliche Kommandozeilen-Einzeiler für LaTeX

Unter https://gist.github.com/iwishiwasaneagle/2f91f63f3cb0107b94b501aa284a18ca gibt es eine Sammlung an nützlichen Einzeilern für die Arbeit mit LaTeX.