Skip to content

Instantly share code, notes, and snippets.

@hansemro
Last active December 27, 2024 09:18
Show Gist options
  • Save hansemro/3c7016f216378845625c7ede166f8d98 to your computer and use it in GitHub Desktop.
Save hansemro/3c7016f216378845625c7ede166f8d98 to your computer and use it in GitHub Desktop.
[WIP] scopehal-docs LaTeX (*.tex) to reStructuredText (*.rst) converter
\chapter{Legal Notices}
\label{ch:legal}
\section{Introduction}
ngscopeclient, libscopehal, and the remainder of the project are all released under the 3-clause BSD license
(reproduced below). This is a permissive license, explicitly chosen to encourage integration with third-party open
source and commercial projects.
\section{License Agreement}
\label{license}
Copyright (c) 2012-2024 Andrew D. Zonenberg and contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
following conditions are met:
\begin{itemize}
\item Redistributions of source code must retain the above copyright notice, this list of conditions, and the
following disclaimer.
\item Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the
following disclaimer in the documentation and/or other materials provided with the distribution.
\item Neither the name of the author nor the names of any contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
\end{itemize}
THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
\section{Trademarks}
This document frequently mentions the names of various test equipment vendors and products in order to discuss
ngscopeclient's compatibility with said products. The reader should assume that these are all trademarks of their
respective owners.
\chapter{TeX to reStructuredText Conversion Tests}
\section{Misc. Formatting}
% \& -> &
This \& that
% \_ -> _
Escaped underscore: \_
% -{}- -> --
-{}-foo This enables the foo function
% \^ -> +
C\^\^
C++
% \today
Today's date: \today
% \degree
90\degree
% \textdegree
180\textdegree
% inline comment
% adjacent comment
%%%%%%%%%%%%%%%
% \0 -> %
\032x
\016x
% \# -> #
\#CAFEF00D
% \pagebreak
\pagebreak
% \FloatBarrier
\FloatBarrier
\section{Text Formatting}
% ``Text" -> "Text"
Outside. ``Quoted text." Outside.
``Inline quoted text" | ``Long quoted
text." | ``Another
long
quote."
% `Text' -> 'Text'
Outside. `Quoted text.' Outside.
`Inline quoted text' | `Long
quoted
text.' | `Another
long
quote.'
% \texttt{Text} -> ``Text``
\texttt{Text}
\texttt{Long
text
description}
\texttt{Inline} | \texttt{Multi-
line
description} | \texttt{Another
multiline
description} | \texttt{Inline}
% \menustyle{Text} -> ``Text``
\menustyle{Text}
\menustyle{Long
text
description}
% \lstinline{Text} -> ``Text``
\lstinline{Text}
\lstinline{Long
text
description}
% \emph{Text} -> *Text*
\emph{Text}
\emph{Long
text
description}
% \cellcolor{color}\textcolor{Text}{color}
\cellcolor{error}\textcolor{Text}{\#00ff00}
\cellcolor{address}\textcolor{Text}{\#ffff00}
\section{Links \& References}
% \issue{repo-name}{number} -> `repo-name:number <https://github.com/ngscopeclient/repo-name/issues/number>`_
\issue{scopehal}{26}
% \href{link}{Text} -> `Text <link>`_
\href{https://www.ngscopeclient.org/}{ngscopeclient}
\href{link}{text} \href{https://www.ngscopeclient.org/}
{ngscopeclient} \href{https://www.ngscopeclient.org/}{ngscopeclient
homepage}
% \hyperref[entity]{Text} -> :ref:`Text <entity>`
\hyperref[license]{License}
\hyperref[entity]{text} \hyperref[entity2]{entity2
description} \hyperref[entity3]
{entity3 description}
% Fig. \ref{entity} -> :numref:`entity`
As shown in Fig. \ref{fig_fruit}, ...
As shown in Fig.
\ref{fig_fruit}, ...
% Chapter \ref{entity} -> :numref:`entity`
In Chapter \ref{ch:legal}, ...
In Chapter
\ref{ch:legal}, ...
\section{\LaTeX Math}
\subsection{Inline Math with $...$}
% $latex$ -> :math:`latex`
$I^2C$
\subsection{Not Math}
\lstinline{cmake .. -DCMAKE_PREFIX_PATH="$(brew --prefix);$(brew --prefix)/opt/libomp"}
\begin{lstlisting}[language=sh, numbers=none]
cd ~
git clone --recursive https://github.com/ngscopeclient/scopehal-apps.git
cd scopehal-apps
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$(brew --prefix);$(brew --prefix)/opt/libomp"
make -j4
\end{lstlisting}
\section{Unordered Lists}
\begin{itemize}
\item entry1 \\
long entry1 description
\item entry2
\item entry3
\end{itemize}
\section{Ordered Lists}
\begin{enumerate}
\item entry1 \\
long entry1 description
\item entry2
\item entry3
\end{enumerate}
\section{Section}
\subsection{Subsection}
\subsection{Subsection with Label}
\label{labeled_subsection}
\subsubsection{Subsubsection}
\section{Figures}
\subsection{Single Image with Caption and Label}
\begin{figure}[h]
\centering
\includegraphics[width=16cm]{image/fig.png}
\caption{A
fig
fruit}
\label{fig_fruit}
\end{figure}
\subsection{Single Image without Caption and Label}
\begin{figure}[h]
\centering
\includegraphics[width=16cm]{image/fig.png}
\end{figure}
\section{Tables}
\begin{tabularx}{16cm}{llX}
\thickhline
\textbf{Device Family} & \textbf{Driver} & \textbf{Notes} \\
\thickhline
Internal Logic Analyzer IP & akila & \\
\thickhline
BLONDEL Oscilloscope Prototype & aklabs & \\
\thickhline
\end{tabularx}
\begin{tabularx}{16cm}{lllXX}
\thickhline
\textbf{Channels} & \textbf{Memory depth} & \textbf{Sample Rate} & \textbf{WFM/s} & \textbf{UI-unconstrained WFM/s}\\
\thickhline
2 & 1M & 100MS/s & 14 & 50\\
\thinhline
2 & 5M & 500MS/s & 4.5 & 14\\
\thinhline
1 & 5M & 1GS/s & 8.3 & 32\\
\thickhline
\end{tabularx}
\section{Code Blocks}
\begin{lstlisting}[language=sh, numbers=none]
source "$HOME/VulkanSDK/1.3.275.0/setup-env.sh"
\end{lstlisting}
\begin{lstlisting}[language=sh, numbers=none]
pacman -S mingw-w64-ucrt-x86\_64-vulkan-headers mingw-w64-ucrt-x86\_64-vulkan-loader mingw-w64-ucrt-x86\_64-shaderc \
mingw-w64-ucrt-x86\_64-glslang mingw-w64-ucrt-x86\_64-spirv-tools
\end{lstlisting}
\section{Footnotes}
Outside. \footnote{This is a footnote.} Outside. \footnote{This
is
another
footnote.} \footnote{This is the third footnote.}
\section{Comments}
\begin{comment}
\subsection{File arguments}
\label{import}
The file extension is used to determine the format. File extensions are case sensitive and must be lowercase to be
correctly interpreted.
\end{comment}
#!/usr/bin/env bash
# Copyright (c) 2024 Hansem Ro
# SPDX-License-Identifier: MIT
# a very terrible (and hopefully very temporary) scopehal-docs LaTeX (*.tex) to reStructuredText (*.rst) converter
set -euo pipefail
# debug: copies to ./tmp/
#TEX=$(basename $1)
#RST=tmp/${TEX%.tex}.rst
TEX=$1
RST=${TEX%.tex}.rst
if [ -f "$RST" ]; then
echo "file $RST exists; quitting"
exit 1
#cp $1 $RST
else
cp $1 $RST
fi
# Misc. Formatting:
# \& -> &
sed -i 's/\\&/\&/g' $RST
# \_ -> _
sed -i 's/\\_/\_/g' $RST
# -{}- -> --
sed -i -E 's/-\{\}-/--/g' $RST
# \\EOL -> EOL
#sed -i 's/\s+\\\\$//g' $RST
# \^ -> +
sed -i 's/\\\^/+/g' $RST
# \today -> month day, year
sed -i 's/\\today/'"$(date +"%b %d, %Y")"'/g;' $RST
# \degree -> ^\circ
sed -i 's/\\degree/\\^circ/g' $RST
# \textdegree -> ^\circ
sed -i 's/\\textdegree/\\^circ/g' $RST
# % -> ..
#sed -i 's/^%\+[^%]\+/..//g' $RST
# remove %%...%%%%
sed -i 's/^%\+$//g' $RST
# \0 -> %
sed -i 's/\\0/%/g' $RST
# \# -> #
sed -i 's/\\#/#/g' $RST
# \pagebreak -> .. raw:: latex\n\n \newpage
sed -i 's/^\\pagebreak$/.. raw:: latex\n\n \\newpage\n/g' $RST
# TODO: \FloatBarrier
# ``text" -> "text"
sed -i -z '/``/,/"/{s/``/"/g;}' $RST
# `text' -> 'text'
sed -i -z '/`/,/'\''/{s/`/'\''/g;}' $RST
# \texttt{text} -> ``text``
sed -i '/\\texttt{/{
/\\texttt{[^}]\+$/{
:start;
H;
# append next lines of input to hold space until we encounter a closing curly brace
:x; s/.*//; N; H; /}/!bx;
# repeat if necessary
/\\texttt{[^}]\+$/bstart;
g;
s/^\n//;
s/\n\+/ /g
};
s/\\texttt{\([^}]\+\)}/``\1``/g
}' $RST
# \menustyle{text} -> ``text``
sed -i '/\\menustyle{/{
/\\menustyle{[^}]\+$/{
:start;
H;
# append next lines of input to hold space until we encounter a closing curly brace
:x; s/.*//; N; H; /}/!bx;
# repeat if necessary
/\\menustyle{[^}]\+$/bstart;
g;
s/^\n//;
s/\n\+/ /g
};
s/\\menustyle{\([^}]\+\)}/``\1``/g
}' $RST
# \lstinline{text} -> ``text``
sed -i '/\\lstinline{/{
/\\lstinline{[^}]\+$/{
:start;
H;
# append next lines of input to hold space until we encounter a closing curly brace
:x; s/.*//; N; H; /}/!bx;
# repeat if necessary
/\\lstinline{[^}]\+$/bstart;
g;
s/^\n//;
s/\n\+/ /g
};
s/\\lstinline{\([^}]\+\)}/``\1``/g
}' $RST
# \emph{text} -> *text*
sed -i '/\\emph{/{
/\\emph{[^}]\+$/{
:start;
H;
# append next lines of input to hold space until we encounter a closing curly brace
:x; s/.*//; N; H; /}/!bx;
# repeat if necessary
/\\emph{[^}]\+$/bstart;
g;
s/^\n//;
s/\n\+/ /g
};
s/\\emph{\([^}]\+\)}/*\1*/g
}' $RST
# TODO: \cellcolor{color}
# see ngscopeclient-manual.tex for defined colors
# TODO: \textcolor{text}{color}
# \issue{repo-name}{number} -> `repo-name:number <https://github.com/ngscopeclient/repo-name/issues/number>`_
sed -i 's,\\issue{\([^}]\+\)}{\([^}]\+\)},`\1:\2 <https://github.com/ngscopeclient/\1/issues/\2>`_,g' $RST
# \url{link} -> link
sed -i 's/\\url{\([^}]\+\)}/\1/g' $RST
# \href{link}{text} -> `text <link>`_
sed -i '/\\href{/{
/\\href{[^}]\+}\({[^}]\+\)\?$/{
H;
# append next lines of input to hold space until we encounter a closing curly brace
:x; s/.*//; N; H; /}/!bx;
# repeat if necessary
/\\href{[^}]\+}\({[^}]\+\)\?$/bx;
g;
s/^\n//;
s/\n\+/ /g;
};
s/\\href{\([^}]\+\)}\s*{\([^}]\+\)}/`\2 <\1>`_/g;
}' $RST
# \hyperref[entity]{text} -> :ref:`text <entity>`
sed -i '/\\hyperref\[/{
/\\hyperref\[[^]]\+\]\({[^}]\+\)\?$/{
H;
# append next lines of input to hold space until we encounter a closing curly brace
:x; s/.*//; N; H; /}/!bx;
# repeat if necessary
/\\hyperref\[[^]]\+\]\({[^}]\+\)\?$/bx;
g;
s/^\n//;
s/\n\+/ /g;
};
s/\\hyperref\[\([^]]\+\)\]\s*{\([^}]\+\)}/:ref:`\2 <\1>`/g;
}' $RST
# Fig. \ref{entity} -> :numref:`entity`
sed -i '/Fig\./{
/Fig\.\(\s*\\ref{[^}]\+}\)\?$/{
H;
# append next lines of input to hold space until we encounter a closing curly brace
:x; s/.*//; N; H; /}/!bx;
# repeat if necessary
/Fig\.\(\s*{[^}]\+\)\?$/bx;
g;
s/^\n//;
s/\n\+/ /g;
};
s/Fig\. \\ref{\([^}]\+\)}/:numref:`\1`/g
}' $RST
# Chapter \ref{entity} -> :numref:`entity`
sed -i '/Chapter/{
/Chapter\(\s*\\ref{[^}]\+}\)\?$/{
H;
# append next lines of input to hold space until we encounter a closing curly brace
:x; s/.*//; N; H; /}/!bx;
# repeat if necessary
/Chapter\(\s*{[^}]\+\)\?$/bx;
g;
s/^\n//;
s/\n\+/ /g;
};
s/Chapter \\ref{\([^}]\+\)}/:numref:`\1`/g
}' $RST
# TODO: find more robust way to skip conversion if part of code listing...
# - Currently, we attempt to ignore shell environment variables by detecting "$ or '$ sequence
# $latex$ -> :math:`latex`
sed -i '/\$/{
/"\$\|'\''\$/!{s/\$\([^$]\+\)\$/:math:`\1`/g;};
}' $RST
# Unordered List:
# \begin{itemize}
# \item value -> * value
# \end{itemize}
sed -i '/\\begin{itemize}/,/\\end{itemize}/{
/\\begin{itemize}/{s/.*//; h; d;};
/\\item/{ s/^\\item\s\+/* /; s/\s*\\\\$/\n/; H; d; };
/\\\(begin{itemize}\|item\|end{itemize}\)/!{ s/^\(.\+\)$/ \1/; s/\s*\\\\$/\n/; H; d; };
/\\end{itemize}/{ g; s/^\n//; p; d; };
}' $RST
# Ordered List:
# \begin{enumerate}
# \item value -> #. value
# \end{enumerate}
sed -i '/\\begin{enumerate}/,/\\end{enumerate}/{
/\\begin{enumerate}/{s/.*//; h; d;};
/\\item/{ s/^\\item\s\+/#. /; s/\s*\\\\$/\n/; H; d; };
/\\\(begin{enumerate}\|item\|end{enumerate}\)/!{ s/^\(.\+\)$/ \1/; s/\s*\\\\$/\n/; H; d; };
/\\end{enumerate}/{ g; s/^\n//; p; d; };
}' $RST
# \chapter{title}[\n\label{entity}] -> [.. _entity:\n\n]title\n=====
sed -i '/\\chapter{\([^}]*\)}/ {
s//\1\n/;
h;
s/\S\| /=/g;
x;
G;
s/\n//;
h;
N;
/\\label/{
s/.*\\label{\([^}]\+\)}/.. _\1:\n/;
G;
};
}' $RST
# \section{section title}[\n\label{entity}] -> .. _entity:\n\nsection title\n-------------
sed -i '/\s*\\section{\([^}]*\)}/ {
s//\1\n/;
h;
s/\S\| /-/g;
x;
G;
s/\n//;
h;
N;
/\\label/{
s/.*\\label{\([^}]\+\)}/.. _\1:\n/;
G;
};
}' $RST
# \subsection{subsection title}[\n\label{entity}] -> .. _entity:\n\nsubsection title\n~~~~~~~~~~~~~~~~
sed -i '/\s*\\subsection{\([^}]*\)}/ {
s//\1\n/;
h;
s/\S\| /~/g;
x;
G;
s/\n//;
h;
N;
/\\label/{
s/.*\\label{\([^}]\+\)}/.. _\1:\n/;
G;
};
}' $RST
# \subsubsection{subsubsection title}[\n\label{entity}] -> .. _entity:\n\nsubsubsection title\n^^^^^^^^^^^^^^^^^^^
sed -i '/\s*\\subsubsection{\([^}]*\)}/ {
s//\1\n/;
h;
s/\S\| /^/g;
x;
G;
s/\n//;
h;
N;
/\\label/{
s/.*\\label{\([^}]\+\)}/.. _\1:\n/;
G;
};
}' $RST
# Figures:
# latex:
# \begin{figure}[h]
# \centering -> Enable Centering
# \includegraphics[width=size]{image-path}
# or
# \bigimage{image-path}
# ...
# \includegraphics[width=size]{image-path2}
# ...
# \caption{fig-caption}
# \label{fig-label}
# \end{figure}
#
# rST:
# .. _fig-label:
# .. subfigure::
# :align: center
#
# .. image:: image-path
#
# .. image:: image-path2
#
# ...
#
# fig-caption
sed -i '/\\begin{figure}/,/\\end{figure}/{
/\\begin{figure}/{
s/\\begin.*/.. subfigure:/;
h;
d;
};
/\\centering/{
s/\s*\\centering/ :align: center/;
H;
d;
};
# append one or more image paths to hold space
/\\\(includegraphics\|bigimage\)/{
s/\s*\\\(includegraphics\[[^]]\+\]\|bigimage\){\([^}]\+\)}/\n .. image:: \2\n/g;
H;
d;
};
# append caption to hold space
/\\caption{/{
/\\caption{[^}]\+$/{
# append next lines of input to pattern space until we encounter a closing curly brace
:x; N; /}/!bx;
s/\n\+/ /g;
};
s/\\caption{\([^}]\+\)}/ \1\n/g;
H;
d;
};
# append label to front of hold space
/\\label/{
s/\s*\\label{\([^}]\+\)}/.. _\1:/;
x;
s/^\n//g;
H;
d;
};
# write out the hold space
/\\end{figure}/{
x;
p;
d;
};
}' $RST
# Tables:
# latex:
# \begin{tabularx}{16cm}{llx}
# \thickhline
# \textbf{Header 1} & \textbf{Header 2} & \textbf{Header 3} \\
# \thickhline
# row1 col1 & row1 col2 & row1 col3 \\
# row2 col1 & row2 col2 & row2 col3 \\
# \thickhline
# \end{tabularx}
#
# rST:
# .. list-table::
# :header-rows: 1
#
# * - Header 1
# - Header 2
# - Header 3
# * - row1 col1
# - row1 col2
# - row1 col3
# * - row2 col1
# - row2 col2
# - row2 col3
#
sed -i '/\\begin{tabularx}/,/\\end{tabularx}/{
/\\begin{tabularx}/{
s/\\begin.*/.. list-table::\n :header-rows: 1\n/g;
h;
d;
};
/\\thi\(ck\|n\)hline/d;
/\\\(begin\|end\){/!{
# append lines to pattern space until it ends with \\
/\\\\$/!{
:x; N; /\\thi\(ck\|n\)hline/bx; /\\\\$/!bx;
s/\n\+/ /g;
};
s/\\textbf{\([^}]\+\)}/\1/g;
s/\s*\\\\$//;
s/^/ * - /;
s/\s*&\s*/\n - /g;
H;
d;
};
/\\end{tabularx}.*/{
g;
p;
d;
};
}' $RST
# Code Blocks:
# \begin{lstlisting}[language=lang, numbers=none]
# code...
# code...
# code...
# \end{lstlisting}
sed -i -e '/\\begin{lstlisting}/,/\\end{lstlisting}/{s/\(\s*\)\(.*\)/ \1\2/g;s/ \(\s*\)\\begin{lstlisting}\[language=\([^],]\+\).*\]/\n\1.. code-block:: \2\n/g;s/\s*\\end{lstlisting}/\n/g}' $RST
# Footnotes:
# latex:
# some text \footnote{note} more text \footnote{second
# note}
#
# rST:
# some text [#]_ more text [#]_
#
# and after first encountered empty line...
# .. [#] note
#
# .. [#] second note
sed -i '/\\footnote{/{
/\\footnote{[^}]\+$/{
# append next lines of input to pattern space until we encounter a closing curly brace
:x; N; /}/!bx;
# repeat if we encounter another open \\footnote{
/\\footnote{[^}]\+$/bx;
s/\n\+/ /g;
};
# append next lines of input to pattern space until we find an empty line
:y; N; /\n$/!by;
# preserve lines in hold space
h;
# replace \\footnote{...} with [#]_
s/\\footnote{[^}]\+}/[#]_/g;
# swap modified lines with original lines
x;
# remove all but \\footnote{...} and place them on separate lines prefixed by `.. [#] ` and their contents
s/^/\n/;
s/\(\\footnote{[^}]\+}\)/\n\1\n\n/g;
s/\(\n\+\)[^\]\+\n/\1/g;
s/\\footnote{\([^}]\+\)}/.. [#] \1/g;
H;
g;
}' $RST
# Multiline-comments:
# latex:
# \begin{comment}
# content1
# content2
# \end{comment}
#
# rST:
# ..
# content1
# content2
#
sed -i '/\\begin{comment}/,/\\end{comment}/{
/\\begin{comment}/{
s/.*/../;
h;
d;
};
/\\end{comment}/!{
s/^/ /;
H;
d;
};
/\\end{comment}/{
g;
p;
d;
};
}' $RST
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment