Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1456 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  Extraire les \newcommand d'un source Latex

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Extraire les \newcommand d'un source Latex

n°2454294
dhenin
Posté le 14-09-2023 à 15:29:03  profilanswer
 

Bonjour.  
Après de nombreuses heures de recherche, en vain, avec l'intention de parcourir mes sources LaTeX pour en isoler les tikzpictures, qui nécessitent des \newcommand, des \tikzset  ...,  j'ai fini par opter pour  Text::Balanced qw(extract_multiple extract_bracketed); et comme c'est loin d'être trivial autant laisser une place à la poursuite. 80)
 
Ce script parcourt les fichiers LaTeX dans un répertoire donné, extrait les blocs \tikzpicture, les commandes \newcommand et les commandes \tikzset, puis génère de nouveaux fichiers LaTeX pour chaque bloc tikzpicture avec les commandes appropriées incluses. Ces nouveaux fichiers garderont leur nom d'origine préfixé de la date de création et suffixé d'un numéro d'ordre pour chaque tikzpicture

Citation :


 
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use File::Basename;
use POSIX qw(strftime);
use Text::Balanced qw(extract_multiple extract_bracketed);
 
#Un seul argument (répertoire source).
die "Usage: $0 <repertoire_de_depart>\n" unless @ARGV == 1;
 
my ($input_directory) = @ARGV;
 
# Définissez le répertoire de sortie où les fichiers seront enregistrés.
my $output_directory = "../Travaux_en_cours/tikzpictures/";
 
# Initialisation de variables.
my $num = 1;            # Numéro de départ
my $date = "";
my $filename = "";
my @newcommands = ();
my @tikzsets = ();
my $suffix = "";
my $file_contents = "";
my $content = "";
my $substring = "";
my $remainder = "";
my $prefix = "";
 
# Parcourir le répertoire  
find(\&extract_tikzpictures, $input_directory);
 
# Extraire les blocs tikzpicture.
sub extract_tikzpictures {
    if (-f $_ && /\.tex$/) {
        {
            local $/ = undef;
            open my $file, "<", $_ or die "Impossible d'ouvrir le fichier $_ : $!";
            $file_contents = <$file>;
            close $file;
 
            # Date de création du fichier.
            if (my ($atime) = (stat $_)[8]) {
                $date = strftime("%y%m%d", localtime($atime));
            } else {
                return; # Ne pas traiter les fichiers sans date de création.
            }
            ($filename, $suffix) = fileparse($_, qr/\.[^.]*/);
 
            # Tableaux pour stocker les commandes \newcommand et \tikzset
            @newcommands = ();
            @tikzsets = ();
 
            $num = 1;
 
            # Premier balayage pour extraire les commandes \newcommand
            my @matches = extract_multiple($file_contents, [
                sub { extract_bracketed($_[0], '{}') },
                #                 qr/(?:\\newcommand|\\renewcommand)(\\[^{}]*)(\{[^{}]*\})/s,
            ]);
 
            for my $i (0 .. $#matches / 2) {
                $prefix = $matches[$i * 2];      # Élément pair (préfixe)
                $content = $matches[$i * 2 + 1]; # Élément impair (contenu)
 
                # Affichez le préfixe et le contenu du couple actuel, sauf si le préfixe est vide ou ne contient pas "newcommand".
                unless (!$prefix || $prefix =~ /newcommand/) {
                    $prefix =~ s/^[^\n%]*%/%/gm;
                    push @newcommands, "$prefix$content";
                }
            }
 
            # Deuxième balayage pour extraire les commandes \tikzset
            @matches = extract_multiple($file_contents, [
                sub { extract_bracketed($_[0], '{}') },
                qr/\\tikzset/s,
            ]);
 
            for my $i (0 .. $#matches / 2) {
                $prefix = $matches[$i * 2];      # Élément pair (préfixe)
                $content = $matches[$i * 2 + 1]; # Élément impair (contenu)
 
                # Idem pour  "tikzset".
                unless (!$prefix || $prefix =~ /tikzset/) {
                    $prefix =~ s/^[^\n%]*%/%/gm;
                    $prefix =~ s/^[^\n%]*%//gm;
                    push @tikzsets, "$prefix$content";
                }
            }
 
            # Divisez le contenu du fichier en blocs tikzpicture.
            my @tikzpictures = ();
            my $tikzpicture = "";
            @tikzpictures = ();
            @tikzpictures = split /\\begin\{tikzpicture\}/, $file_contents;
 
            # Le premier élément (index 0) est vide car il précède la première \begin{tikzpicture}.
            shift @tikzpictures; # Supprimez le premier élément vide
 
            # Supprimer les espaces en début et fin de chaque tikzpicture si nécessaire
            # s/^\s+|\s+$//g for @tikzpictures;
 
            my $nombre_elements = scalar @tikzpictures;
 
            foreach my $dessin (@tikzpictures) {
                my $num_str = sprintf("%02d", $num);
                my $output_filename = $date . "_" . $filename . "_" . $num_str . ".tex";
                my $output_path = $output_directory . $output_filename;
 
                open my $output_file, ">", $output_path or die "Impossible de créer le fichier $output_path : $!";
 
                # Écrire le contenu du bloc d'entête dans le fichier de sortie.
                # Ce bloc facilitera la compilation isolée ou depuis un appel \input précédé de define COMPLETE  
                print $output_file "\\ifdefined\\COMPLETE\n";
                print $output_file "\\else\n";
                print $output_file "    \\input{/Users/dhenin/Desktop/14_Travaux_en_cours/preambule_texte.tex}\n";
                print $output_file " %   \\input{/Users/dhenin/Desktop/14_Travaux_en_cours/preambule-utf8.ltx}\n";
                print $output_file "    \\begin{document}\n";
                print $output_file "\\fi\n\n";
 
                # Inclure les commandes \newcommand et \tikzset du fichier d'origine.
                print $output_file join("\n", @newcommands) . "\n";
                print $output_file join("\n", @tikzsets) . "\n";
 
                # Inclure le bloc de dessin dans le fichier de sortie.
                print $output_file "\\begin{tikzpicture}$dessin";
 
                # Inclure la partie finale du fichier de sortie, y compris la fin du document LaTeX.
                print $output_file "\\ifdefined\\COMPLETE\n";
                print $output_file "\\else\n";
                print $output_file "    \\end{document}\n";
                print $output_file "\\fi\n";
 
                close $output_file;
 
                $num++; # Incrémenter le numéro de fichier pour le prochain bloc tikzpicture
            }
        }
    }
}
 


 
Attention s'il y a des include graphics ils ne sont pas traités.
Pour compiler les fichiers céées : for i in *.tex ; do  pdflatex -halt-on-error  -interaction=nonstopmode $i.tex  ; done
 
Bonjour chez vous

mood
Publicité
Posté le 14-09-2023 à 15:29:03  profilanswer
 

n°2454386
gilou
Modérateur
Modzilla
Posté le 16-09-2023 à 14:40:56  profilanswer
 

Citation :

@tikzpictures = split /\\begin\{tikzpicture\}/, $file_contents;
# Le premier élément (index 0) est vide car il précède la première \begin{tikzpicture}.
shift @tikzpictures; # Supprimez le premier élément vide


 
OK jusque la, mais après, je ferais  
@tikzpictures = map {shift(split(/\\end\{tikzpicture\}/, $_))}, @tikzpictures;
pour ne récupérer dans @tikzpictures que les portions qui étaient entre un \begin{tikzpicture} et un \end{tikzpicture}
ou @tikzpictures = map {'\\begin{tikzpicture}\n'.shift(split(/\\end\{tikzpicture\}/, $_)).'\n\\end{tikzpicture}'}, @tikzpictures;
si tu les veux avec délimiteur
 
Bon, c'est sans garantie, car je ne code presque plus en perl ces derniers temps.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2454395
Hermes le ​Messager
Breton Quiétiste
Posté le 17-09-2023 à 15:58:48  profilanswer
 

Pourquoi ne pas utiliser une librairie de parsing latex, genre : https://github.com/xemlock/php-latex
 


---------------
Expert en expertises

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  Extraire les \newcommand d'un source Latex

 

Sujets relatifs
Extraire image lien avec Beautiful SoupScript bash/python extraire données bdd
Modifier du code source VBA à la voléeLicence open source et fork de projet
[PowerShell]Extraire un ID matérielextraire dans une variable le contenu d'une structure
Extraire un mot entre deuxvirgules dans une chaine[PHP] - Extraire chemins des fichiers mp3 dans balise audio
[latex] Création de liste dans un templateIntéger les data d'une image au source HTML
Plus de sujets relatifs à : Extraire les \newcommand d'un source Latex


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR