TexSurgery
CTAN: https://ctan.org/pkg/texsurgery (New on CTAN since 2021-07-10)
Repository: https://framagit.org/pang/texsurgery
I use pipenv to satisfy requirements
mkdir demo-texsurgery && cd demo-texsurgery
pipenv install texsurgery pyparsing
For installation of Jupyter kernels see the corresponding instructions of the respective kernel, e.g.
https://github.com/gap-packages/JupyterKernel#installation.
Apply manually an unreleased fix for texsurgery 0.6.3 (on pypi as of March 2023) to allow kernel names with a - (here gap-4):
https://framagit.org/pang/texsurgery/-/commit/86d8902e3e592371d191d42517dd41eacc21fd5a
Create a demo file
% file: demo-texsurgery-hello-gap-kernel.tex
\documentclass{article}
\usepackage[gap-4]{texsurgery} % specify kernel
\begin{document}
Here comes output of the GAP Jupyter Kernel:
\begin{run}
modtbl:= CharacterTable( "L3(2)" ) mod 2;;
Print( LaTeXStringDecompositionMatrix( modtbl, 1 ) );
\end{run}
\end{document}
texsurgery pre-processes the document and outputs a new document with replaced parts. You can combine a run of texsurgery and pdflatex as following (here with pipenv prefixed):
pipenv run texsurgery demo-texsurgery-hello-gap-kernel.tex -pdf --pdflatex-options -synctex=1
The result looks like:

Note, texsurgery allows to use several Jupyter kernels in one document which is described here:
https://framagit.org/pang/texsurgery/-/blob/master/docs/source/kernels.md
ADDITION: TikZ visualisation for primes and twin primes smaller than 2500 with the GAP Package IntPic
\documentclass{article}
\usepackage[gap-4]{texsurgery} % specify kernel
\usepackage[landscape]{geometry} % tikz matrix is too wide
% for the gap package IntPic generating TikZ code
\usepackage{amsmath}
\usepackage{tikz}
\usepgfmodule{plot}
\usepgflibrary{plothandlers}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{shadings}
\begin{runsilent}
LoadPackage("Singular");
LoadPackage("IntPic");
SetPrintFormattingStatus("stdout", false);
\end{runsilent}
\begin{document}
\begin{run}
row_length := 100;; # the maximum length of a row
nrows := 25;; # the number of rows; TIMEOUT Error for 50
n := row_length*nrows;;
##compute the primes less than n
Primes is a GAP variable representing the list of primes less than n
mp := Maximum(Primes);;
newprimes := [];;
while mp < n do
mp := NextPrimeInt(mp);;
Add(newprimes, mp);;
od;
small_primes := Union(Primes, newprimes);;
##compute the first element of each pair of twin primes less than n
twins := Filtered(small_primes, p -> IsPrime(p+2));;
rg := [1..n];;
arr := [Intersection(small_primes,rg),[],[],
Intersection(Union(twins,twins+2),rg),[],[],[],[],[],[],[],
[],[],[],[],[],[],Difference(rg,small_primes)];;
Print(IP_TikzArrayOfIntegers([1..n],row_length,rec(highlights:=arr,
cell_width := "6",colsep:="0",rowsep:="0",inner_sep:="2",
shape_only:="",line_width:="0",line_color:="black!20" )));
\end{run}
\end{document}

\immediate\write18to run the code and save it to a file, and then input the file. – Teepeemm Nov 05 '18 at 18:55