%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % pyjupyter.sty % Python code environment styled for Jupyter-like listings % Author : BARA Ouyèté Bright % Date : 2026/03/11 %License: LPPL v1.3c %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{pyjupyter}[2026/03/06 Python Jupyter-style listings] \PassOptionsToPackage{dvipsnames,svgnames,table}{xcolor} \RequirePackage{xcolor} \RequirePackage{listingsutf8} \RequirePackage{tcolorbox} \tcbuselibrary{listings,skins,breakable} \IfFileExists{sourcecodepro.sty}{ \RequirePackage{sourcecodepro} }{ \PackageWarning{pyjupyter}{Package 'sourcecodepro' not found. Using default monospaced font} } \RequirePackage{kvoptions} \SetupKeyvalOptions{family=pyj,prefix=pyj@} \makeatletter \DeclareStringOption[sourcecodepro]{font} \DeclareStringOption[small]{codesize} \ProcessKeyvalOptions* \IfFileExists{sourcecodepro.sty}{\RequirePackage{sourcecodepro}}{} \IfFileExists{beramono.sty}{\RequirePackage{beramono}}{} \IfFileExists{zi4.sty}{\RequirePackage{zi4}}{}%inconsolata font \newcommand{\pyj@selectedfont}{ \def\pyj@temp{sourcecodepro} \ifx\pyj@font\pyj@temp \fontfamily{SourceCodePro-TLF}\selectfont \else \def\pyj@temp{beramono} \ifx\pyj@font\pyj@temp \fontfamily{fvm}\selectfont \else \def\pyj@temp{inconsolata} \ifx\pyj@font\pyj@temp \fontfamily{zi4}\selectfont \else \def\pyj@temp{lmtt} \ifx\pyj@font\pyj@temp \fontfamily{lmtt}\selectfont \else \def\pyj@temp{courier} \ifx\pyj@font\pyj@temp \fontfamily{pcr}\selectfont \else \def\pyj@temp{txtt} \ifx\pyj@font\pyj@temp \fontfamily{txtt}\selectfont \else \ttfamily \fi\fi\fi\fi\fi\fi } \makeatother \lstset{inputencoding=utf8, extendedchars=true, literate= {é}{{\'e}}1 {è}{{\`e}}1 {ê}{{\^e}}1 {ë}{{\"e}}1 {à}{{\`a}}1 {â}{{\^a}}1 {ä}{{\"a}}1 {ã}{{\~a}}1 {ï}{{\"i}}1 {î}{{\^i}}1 {ì}{{\`i}}1 {í}{{\'i}}1 {ö}{{\"o}}1 {ô}{{\^o}}1 {ò}{{\`o}}1 {ó}{{\'o}}1 {ü}{{\"u}}1 {ù}{{\`u}}1 {û}{{\^u}}1 {ç}{{\c c}}1 {Ç}{{\c C}}1 {É}{{\'E}}1 {È}{{\`E}}1 {Ë}{{\"E}}1} \lstdefinestyle{pyjupyter-syntax}{ language=Python, basicstyle=\pyj@selectedfont\csname\pyj@codesize\endcsname, alsoletter={+, -, *, /, =, <, >, !, \&, |, **, \^, ~, <<, >>, +=, -=,*=, /=, //=, \%=, **=, \&=, |=, \^=, <<=, >>=}, emph={+, -, *, /, =, <, >, !, \&, |, **, \^, ~, <<, >>, +=, -=,*=, /=, //=, \%=, **=, \&=, |=, \^=, <<=, >>=}, emphstyle=\color{violet}, keywordstyle=\color{DarkGreen}\bfseries, keywords={class,def,return,if,else,for,while,in,raise, import,from,as,try,except,with,and,or,not,is, True,False,None,assert,break,continue,del,elif, finally,from,global,import,lambda, nonlocal,pass,yield}, keywordstyle=[2]\color{DarkGreen}, keywords=[2]{print,super,len,range,enumerate,zip, list,dict,set,int,str,float,bool}, keywordstyle=[3]\color{violet}, keywords=[3]{+, -, *, /, =, <, >, !, \&, |, :, **, \^, ~, <<, >>, +=, -=,*=, /=, //=, \%=, **=, \&=, |=, \^=, <<=, >>=}, commentstyle=\color{teal!80!black}\itshape, stringstyle=\color{red!70!black}, showstringspaces=false, escapeinside={@}{@}, breaklines=true, breakatwhitespace=true, tabsize=2, columns=fullflexible, keepspaces=true, upquote=true, morecomment=[s][\color{red!70!black}\itshape]{'''}{'''}, morecomment=[s][\color{red!70!black}\itshape]{"""}{"""} } \tcbset{ numbered/.style={ left=10mm, listing options={ numbers=left, numberstyle=\ttfamily\color{black!60}, numbersep=8pt, style=pyjupyter-syntax, } } } \newtcblisting{jupyter}[1][]{ enhanced, breakable, listing only, listing options={style=pyjupyter-syntax}, colback=gray!5, colframe=gray!30, arc=3pt, boxrule=1pt, boxsep=0.3mm, left=1mm, right=1mm, top=0.3mm, bottom=0.3mm, before=\addvspace{1em}, after=\addvspace{1em}, #1 } \endinput