%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pyjupyter.sty                                           %%                                                     
% Python code environment styled for Jupyter-like listings%%                    
% Author:  BARA Ouyèté Bright                              %%                                       
% Date: 15/03/2026                                        %% 
%Version: 1.2.0                                           %%                                                      
%License: LPPL v1.3c                                      %%                                                
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{pyjupyter}[2026/03/15 Python Jupyter-style listings]


\PassOptionsToPackage{dvipsnames,svgnames,table}{xcolor}
\RequirePackage{xcolor}
\RequirePackage{listings}
\RequirePackage{listingsutf8}
\RequirePackage{etoolbox}
\RequirePackage{tcolorbox}
\tcbuselibrary{listings,skins,breakable,hooks,xparse}

\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/latin1,
    extendedchars=true,
    upquote=true,
}

\lstdefinestyle{pyjupyter}{
    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,
        }
    },
    startline/.style={listing options app={firstline=#1, firstnumber=#1}}, 
    endline/.style={listing options app={lastline=#1}},      
}

\newtcblisting{jupyter}[1][]{
    enhanced,
    breakable,
    listing only,
    listing options={style=pyjupyter},    
    colback=gray!5,
    colframe=gray!30,
    arc=2pt,
    boxrule=1pt,
    boxsep=0.3mm,
    left=1mm, 
    right=1mm,
    top=0.5mm,
    bottom=0.3mm, 
    before=\addvspace{1em},
    after=\addvspace{1em},
    #1
}


\NewDocumentCommand{\inputpythonfile}{O{} m}{
    \tcbinputlisting{
        enhanced,
        breakable,
        listing only,
        listing engine=listings,
        listing file={#2},
        listing options={
            style=pyjupyter},
        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