Notre équipe spécialisée après plusieurs jours de travail et de collecte d'informations, nous trouvons la solution, nous voulons qu'elle vous soit utile dans votre projet.
Solution :
Voici une approximation de ce que vous demandez.
TeX ne fournit pas de moyen d'entrer des fichiers binaires de manière fiable, mais pour pdfTeX, il y a la fonction pdffiledump
primitive pour lire un fichier binaire, échappé comme une séquence de nombres hexadécimaux. Nous devons d'abord prétraiter cette chaîne pour obtenir une séquence de caractères, chacun de code 12 ([email protected]
).
Ensuite, nous analysons cette chaîne d'entrée ([email protected]
), en construisant la ligne de sortie actuelle dans une liste de jetons. [email protected]
(pour des raisons techniques, dans un ordre inversé). En fonction du caractère d'entrée actuel, les éléments de la liste de jetons de sortie sont soit ajoutés, soit supprimés, soit imprimés et une nouvelle liste est commencée.
Chaque fois qu'un caractère d'échappement (x1B
) apparaît, le caractère suivant détermine le type de séquence d'échappement. S'il s'agit d'un [
, ce qui suit est une série de numéros de paramètres, et un caractère final qui spécifie le type de sortie du terminal. Nous nous branchons ensuite sur ce type et le numéro de paramètre donné pour modifier les variables globales pour les attributs d'affichage actuels ([email protected]@termout
). Ces derniers sont pris en compte chaque fois qu'un nouveau caractère est ajouté à la ligne de sortie courante.
Le code complet :
documentclass{article}
usepackage{xcolor}
usepackage{pdftexcmds}
usepackage{mdframed}
usepackage[utf8]{inputenc}
usepackage{textcomp}
makeatletter
endlinechar=-1
% Manipulation of current output line
newif[email protected]@
def[email protected]{}
def[email protected]@push#1{
[email protected]@
def[email protected]{}
fi
xdef[email protected]{
{{noexpandstrut
noexpandcolor{[email protected][email protected]@!75!whitefi}
unexpanded{#1}}}
unexpandedexpandafter{[email protected]}
}
[email protected]@false
}
def[email protected]@pop{
xdef[email protected]{expandafterunexpandedexpandafterexpandafterexpandafter
{expandafter@gobble[email protected]}}
[email protected]@false
}
def[email protected]@print{
leavevmode
expandafter[email protected]@reverseexpandafter@sep[email protected]{}@end
}
def[email protected]@reverse#1@sep#2#3@end{
[email protected]{#3}{
#2#1
}{
[email protected]@reverse#2#1@sep#3@end
}
}
% Display attributes
def[email protected]{}
def[email protected]@fgcolor{lightgray}
newif[email protected]@
% Input parsing
newcount[email protected]@a
newcount[email protected]@b
begingroup
count0=0relax
loop
lccode`*=count0relax
lowercase{
expandaftergdefcsname [email protected]@[email protected]numbercount0endcsname{*}
}
advancecount0 by 1relax
ifnumcount0<256relax
repeat
endgroup
def[email protected]#1#2{
[email protected]{#1}{}{
csname [email protected]@[email protected]number"#1#2endcsname
[email protected]
}
}
def[email protected]#1{
% End of input
[email protected]@eq#1relax{
@@par
[email protected]{}
}{}
% Escape sequence
[email protected]@eq#1[email protected]@char{
[email protected][email protected]@esc
}{}
% Newline
[email protected]@eq#1[email protected]@char{
[email protected]@print
@@par
[email protected][email protected]
}{}
% Carriage return
[email protected]@eq#1[email protected]@char{
[email protected]@true
[email protected][email protected]
}{}
[email protected]@eq#1[email protected]@char{
[email protected]@pop
[email protected][email protected]
}{}
[email protected]@eq#1[email protected]@char{
[email protected]@push{ }
[email protected][email protected]
}{}
[email protected]@range{`#1}{194}{223}{
[email protected]{[email protected]@[email protected]#1}
}{}
[email protected]@range{`#1}{224}{239}{
[email protected]{[email protected]@[email protected]#1}
}{}
[email protected]@range{`#1}{240}{244}{
[email protected]{[email protected]@[email protected]#1}
}{}
[email protected]{
[email protected]@push{#1}
[email protected]
}
}
def[email protected]@esc#1{
[email protected]@eq#1[{
[email protected]@csi
}{
GenericWarning{}{Warning: Ignored unknown escape sequence of type `#1'}
[email protected]
}
}
def[email protected]@csi#1{
[email protected]@b=-1relax
% Is private sequence?
[email protected]@eq#1?{
afterassignment[email protected]@[email protected]
[email protected]@a=0
}{
afterassignment[email protected]@[email protected]
[email protected]@a=0#1
}
}
def[email protected]@[email protected]#1{
% Check for second parameter
[email protected]@eq#1;{
afterassignment[email protected]@termout
[email protected]@b=0
}{
[email protected]@termout #1
}
}
def[email protected]@termout#1{
% SGR parameter
[email protected]@eq#1m{
[email protected]@sgr[email protected]@a
ifnum[email protected]@b<0else
[email protected]@sgr[email protected]@b
fi
[email protected]{}
}{}
[email protected]{
% GenericWarning{}{Warning: Ignored unknown terminal output sequence of type `#1'}
}
[email protected]
}
def[email protected]@sgr#1{
% Reset
[email protected]@eq{#1}{0}{
let[email protected]=[email protected]@fgcolor
[email protected]@false
[email protected]{}
}{}
% Bold/intense
[email protected]@eq{#1}{1}{
[email protected]@true
[email protected]{}
}{}
% Standard colors
[email protected]@eq{#1}{30}{
def[email protected]{black}
[email protected]{}
}{}
[email protected]@eq{#1}{31}{
def[email protected]{red}
[email protected]{}
}{}
[email protected]@eq{#1}{32}{
def[email protected]{green}
[email protected]{}
}{}
[email protected]@eq{#1}{33}{
def[email protected]{yellow}
[email protected]{}
}{}
[email protected]@eq{#1}{34}{
def[email protected]{blue}
[email protected]{}
}{}
[email protected]@eq{#1}{35}{
def[email protected]{magenta}
[email protected]{}
}{}
[email protected]@eq{#1}{36}{
def[email protected]{cyan}
[email protected]{}
}{}
[email protected]@eq{#1}{37}{
def[email protected]{white}
[email protected]{}
}{}
[email protected]{}
}
% n-byte Unicode sequences
def[email protected]@[email protected]#1#2{
scantokens{csname [email protected]@pushendcsname{#1#2}}
[email protected]
}
def[email protected]@[email protected]#1#2#3{
scantokens{csname [email protected]@pushendcsname{#1#2#3}}
[email protected]
}
def[email protected]@[email protected]#1#2#3#4{
scantokens{csname [email protected]@pushendcsname{#1#2#3#4}}
[email protected]
}
% Helper macros
def[email protected]#1{
ifrelaxdetokenize{#1}relax
expandafter@firstoftwo
else
expandafter@secondoftwo
fi
}
def[email protected]@eq#1#2{
if#1#2%
expandafter@firstoftwo
else
expandafter@secondoftwo
fi
}
def[email protected]@eq#1#2{
ifnum#1=#2 %
expandafter@firstoftwo
else
expandafter@secondoftwo
fi
}
def[email protected]@range#1#2#3{
ifnum#1<#2 %
expandafter@firstoftwo
else
expandafter@secondoftwo
fi
{
@secondoftwo
}{
ifnum#1>#3 %
expandafter@secondoftwo
else
expandafter@firstoftwo
fi
}
}
def[email protected]#1#2[email protected]#3{#1}
def[email protected]#1{#1}
def@temp#1#2{
begingroup
lccode`*=`#2
lowercase{globallet#1=*}
endgroup
}
@temp[email protected]@char ^^H
@temp[email protected]@char ^^J
@temp[email protected]@char ^^M
@temp[email protected]@char ^^[
@temp[email protected]@char %
% User macros
% Print terminal session stored in #1
newcommandterminalinput[1]{
begin{mdframed}[
backgroundcolor=black,
innerleftmargin=0pt,
innerrightmargin=0pt,
innertopmargin=0pt,
innerbottommargin=0pt
]
begingroup
parindent=0pt
frenchspacing
ttfamily
fboxsep=0pt
[email protected]@sgr{0}
xdef@temp{[email protected]{0}{[email protected]{#1}}{#1}}
expandafterxdefexpandafter[email protected]expandafter{
expandafter[email protected]@temp{}{}
}
expandafter[email protected][email protected]relax
endgroup
end{mdframed}
}
endlinechar=`^^M
makeatother
DeclareUnicodeCharacter{279C}{textrightarrow}
begin{document}
terminalinput{typescript.bin}
end{document}
sort
Il y a encore plusieurs problèmes avec l'implémentation actuelle :
- Le code ne fonctionne qu'avec le
pdflatex
oulualatex
car il s'appuie sur le compilateurpdffiledump
ou sa réimplémentation en code Lua, respectivement. Actuellement, aucun caractère Unicode n'est pris en charge, car le fichier est décodé comme un flux à un seul octet. Les caractères en dehors de la plage ASCII imprimable sont ignorés pour le moment.
EDIT: Les caractères Unicode sont supportés maintenant. Chaque fois qu'une séquence UTF-8 2/3/4 octets est rencontrée, les octets sont re-mappés vers leurs catcodes standards via.scantokens
de telle sorte queinputenc
puisse faire son travail normalement. De nouveaux mappages de caractères peuvent être ajoutés viaDeclareUnicodeCharacter
.- La "fenêtre du terminal" est actuellement juste une boîte noire s'étendant sur toute la largeur du texte.
- L'implémentation actuelle ne couvre qu'un petit sous-ensemble de toutes les séquences d'échappement/séquences de sortie du terminal disponibles. Plus particulièrement, les couleurs d'arrière-plan ne sont pas gérées du tout, il n'y a qu'une gestion tiède des couleurs grasses/intense (en ajoutant
!75!white
à la couleur actuelle), seules les huit couleurs standard (codes 30-37) sont implémentées, etc. - Le positionnement du curseur n'est pas non plus géré correctement, par exemple le retour chariot (