[Résolu] Fusion de documents LateX

Tout ce qui concerne l'utilisation ou l'installation de LaTeX.

Modérateur: gdm_tex

Règles du forum
Merci d'éviter le style SMS dans vos messages et de penser à utiliser la fonction Recherche avant de poster un message. Pour joindre des fichiers à vos messages, consulter ce sujet.
> Penser à utiliser les balises Code pour poster du code.

[Résolu] Fusion de documents LateX

Messagepar Nollan » Samedi 20 Décembre 2014, 09:15

Bonjour tout le monde,

Voici mon problème:
Je possède plusieurs fichiers, placés à la racine de mon disque dur D, que j'insère dans mes documents latex:
- un fichier "standard.tex" qui importe les packages
- un fichier "commandes.tex" qui importe les .... commandes

Exemple minimal:

Fichier standard.tex:
Code: Tout sélectionner
 
\documentclass[a4paper,10pt]{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[francais]{babel}
\usepackage[a4paper]{geometry}
\usepackage{lmodern}

\input{"D:/commandes.tex"}


Fichier commandes.tex
Code: Tout sélectionner
\renewcommand{\thefootnote}{\fnsymbol{footnote}}


Mon fichier exemple.tex:
Code: Tout sélectionner
\input{"D:/standard.tex"}
\begin{document}
   blablabla....
\end{document}


Evidemment tout marche très bien... sur mon ordinateur.
Mais pour pouvoir transmettre un fichier à un collègue, c'est moins simple.

L'idée serait de pouvoir automatiquement créer un fichier complet, sans avoir à faire de copier-coller, qui ressemblerait à ça:
Code: Tout sélectionner
\documentclass[a4paper,10pt]{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[francais]{babel}
\usepackage[a4paper]{geometry}
\usepackage{lmodern}

\renewcommand{\thefootnote}{\fnsymbol{footnote}}

\begin{document}
   blablabla....
\end{document}


Je pense qu'il est possible de faire ça avec un script Python, mais je ne connais pas Python.

Quelqu'un a-t-il une solution ?
Merci d'avance
Dernière édition par Nollan le Dimanche 21 Décembre 2014, 10:07, édité 1 fois.
Nollan
Déca-utilisateur
 
Messages: 10
Inscription: Lundi 14 Mai 2007, 17:33

Publicité

Re: Fusion de documents LateX

Messagepar marco56 » Samedi 20 Décembre 2014, 12:27

Vouloir utiliser Python, alors qu'on ne connaît pas python, hum, comment dire ?
Soit tu fais du copier-coller, soit ton collègue reprend la même organisation que toi ou dernière solution, tu te mets à python.
Si tu veux une piste pour écrire du LaTeX avec python, voici un exemple :
http://snouffy.free.fr/blog-fr/index.php/post/2010/03/16/Script-Python-pour-r%C3%A9cup%C3%A9rer-une-recette-sur-marmiton.org-et-la-formater-en-LaTeX
marco56
Giga-utilisateur
 
Messages: 759
Inscription: Jeudi 25 Novembre 2010, 22:10
Statut actuel: Actif et salarié | Enseignant

Re: Fusion de documents LateX

Messagepar gigiair » Samedi 20 Décembre 2014, 14:27

Nollan a écrit:Bonjour tout le monde,

Voici mon problème:
Je possède plusieurs fichiers, placés à la racine de mon disque dur D, que j'insère dans mes documents latex:
[snip]

Je pense qu'il est possible de faire ça avec un script Python, mais je ne connais pas Python.

Quelqu'un a-t-il une solution ?
Merci d'avance

Si tu utilises un bon éditeur, c'est facile. Pas besoin de Python (Quand on pose un problème, il vaut mieux éviter d'avoir des préjugés sur la façon de résoudre. C'est le plus sûr moyen de ne jamais y parvenir).

Par exemple avec Emacs, il suffit d'effectuer une recherche et remplacement d'une regexp par un bout de code elisp.
remplacer \\input{\([^}]*\)} par \,(progn(insert-file-contents \1 )""))
Code: Tout sélectionner
M-x query-replace-regexp RET  \\input{\([^}]*\)}  RET  \,(progn(insert-file-contents \1 )""))

Commande que l'on peut lancer par les touches `C-M-S %' (Control-Meta-Shift %)

On peut pour plus de confort créer une commande qui automatise ce traitement. Évaluer dans n'importe quel buffer
Code: Tout sélectionner
(defun query-insert-inputs nil "Remplace tous les \\input{<fichier>} par le \n contenu de <fichier>"
       (interactive)
       (query-replace-regexp "\\\\input{\\([^}]+\\)}"
              '(replace-eval-replacement replace-quote
                     (progn
                       (insert-file-contents
                        (match-string 1))
                       ""))
              nil
              (if
             (and transient-mark-mode mark-active)
             (region-beginning))
              (if
             (and transient-mark-mode mark-active)
             (region-end))
              nil))

Puis ensuite lancer la commande par M-x query-insert-inputs.
Si on souhaite conserver cette fonction et l'activer automatiquement, il suffit de l'enregistrer dans le fichier .emacs .
Elle sera active au prochain redémarrage d'Emacs.


%---------------------------------------
Pour ceux qui ne connaissent pas les expressions régulières (regexp) ;
Tout caractère ordinaire s'unifie avec lui-même.
Les caractères `\' est un caractère spécial qui doit être doublé pour s'unifier avec lui-même.
Les crochets droits sont également des caractères spéciaux qui peuvent contenir un ensemble de caractères candidats à l'unification. Par exemple `[aAbB]' s'unifie à a, A, b ou B.
Le symbole `^' au début d'un ensemble est le symbole de la complémentation. `[^}]' s'unifie à tout caractère différent de `}'.
`*" ou `+' sont des opérateurs de multiplicité : * remplace tout entier naturel et + tout entier naturel non nul. Par exemple `[^}]+' s'unifie à toute chaîne de caractères différents de } et non vide.
Pour capturer une partie de l'expression, il suffit de la placer entre deux parenthèses protégées `\(<..partie capturée..>\)' Ainsi `\\input{\([}]+\)}' s'unifie à toute chaîne du genre `\input{.....}' et la partie entre les accolades est capturée. On peut la restituer par l'expression `\&' (ou \1 \2 ... quand il y a plusieurs expressions capturées)
L'expression `\,' annonce que ce qui suit est du code elisp et doit être évalué. l'évaluation de la forme (insert-file-contents \1) fait exactement ce que l'on attend.

Pour plus de détails, évaluer dans n'importe quelle fenêtre Emacs `(info "(Emacs)regexps")'


%--------------------------------------------------------------

<troll> Voici un exemple de la puissance d'Emacs. Quels autres éditeurs peuvent faire ça d'une seule commande ?</troll>
Dernière édition par gigiair le Mardi 20 Octobre 2015, 10:02, édité 3 fois.
JJR.
LaTeXien migrateur.
gigiair
Exa-utilisateur
 
Messages: 2399
Inscription: Samedi 08 Juillet 2006, 19:56
Localisation: Saint Bonnet Elvert
Statut actuel: Actif et salarié

Re: Fusion de documents LateX

Messagepar rebouxo » Samedi 20 Décembre 2014, 17:49

Ce que tu veux ressemble furieusement à une extension personnelle. Le plus simple serait de créer un .sty (nollan.sty) qui serait placer dans ton texmf personnel. Et de le distribuer à tes collègues.

Olivier
A line is a point that went for a walk. Paul Klee
Par solidarité, pas de MP
rebouxo
Modérateur
 
Messages: 6920
Inscription: Mercredi 15 Février 2006, 13:18
Localisation: le havre
Statut actuel: Actif et salarié | Enseignant

Re: Fusion de documents LateX

Messagepar gigiair » Samedi 20 Décembre 2014, 21:38

rebouxo a écrit:Le plus simple serait de créer un .sty (nollan.sty) qui serait placer dans ton texmf personnel.

Ça ne changerait strictement rien au problème, les .sty seraient à placer exactement dans les mêmes endroits que les .tex, et il faudrait modifier la commande \input en conséquence.
JJR.
LaTeXien migrateur.
gigiair
Exa-utilisateur
 
Messages: 2399
Inscription: Samedi 08 Juillet 2006, 19:56
Localisation: Saint Bonnet Elvert
Statut actuel: Actif et salarié

Re: Fusion de documents LateX

Messagepar Nollan » Dimanche 21 Décembre 2014, 10:06

Bonjour à tous,

J'ai résolu mon problème: je me suis mis à Python :D
J'ai regardé les cours débutant sur Openclassroom (ancien site du zéro), et j'ai pondu le code suivant:

Code: Tout sélectionner
import os
fichier="mon_fichier.tex"
f = open(fichier,"r",)
g = open (fichier[:-4]+"-complet.tex","w")
for i in f.readlines():
    if i[:6]=="\input":
        k=i[8:-3]
        h=open(k,"r")
        contenu=h.read()
        g.write(contenu)
        h.close()
    else:
        g.write(i)

g.close()       
f.close()



Je dois encore automatiser tout ça pour que le programme convertisse tous les fichiers un répertoire (j'ai vu comment faire), et j'aimerai bien intégrer une boite de dialogue au début qui me demande de sélectionner un répertoire ou un fichier.


Merci pour vos réponses !
Nollan
Déca-utilisateur
 
Messages: 10
Inscription: Lundi 14 Mai 2007, 17:33

Re: Fusion de documents LateX

Messagepar marco56 » Dimanche 21 Décembre 2014, 16:37

Nollan a écrit:Bonjour à tous,

J'ai résolu mon problème: je me suis mis à Python :D
J'ai regardé les cours débutant sur Openclassroom (ancien site du zéro), et j'ai pondu le code suivant:

Code: Tout sélectionner
import os
fichier="mon_fichier.tex"
f = open(fichier,"r",)
g = open (fichier[:-4]+"-complet.tex","w")
for i in f.readlines():
    if i[:6]=="\input":
        k=i[8:-3]
        h=open(k,"r")
        contenu=h.read()
        g.write(contenu)
        h.close()
    else:
        g.write(i)

g.close()       
f.close()



Je dois encore automatiser tout ça pour que le programme convertisse tous les fichiers un répertoire (j'ai vu comment faire), et j'aimerai bien intégrer une boite de dialogue au début qui me demande de sélectionner un répertoire ou un fichier.


Merci pour vos réponses !


Bravo !
Pour la boîte de dialogue, tu peux te diriger vers tkinter.
marco56
Giga-utilisateur
 
Messages: 759
Inscription: Jeudi 25 Novembre 2010, 22:10
Statut actuel: Actif et salarié | Enseignant

Re: [Résolu] Fusion de documents LateX

Messagepar Nollan » Dimanche 21 Décembre 2014, 19:28

J'ai suivis vos conseils: j'ai regardé quelques tuto sur tkinter.

J'ai donc un code qui ouvre une boite de dialogue qui permet de choisir de fusionner un seul fichier ou tous les fichiers tex d'un répertoire.
Au passage: ça m'a vraiment donné envie de me mettre sérieusement à Python !!!

Je mets le code en-dessous, si ça peut servir à quelqu'un un jour 8)

Bonne fêtes de fin d'année !

Code: Tout sélectionner
# script fusionner fichiers latex
from tkinter import *
import tkinter.messagebox
import tkinter.filedialog
import os

def Complete(fichier):
    try:
        f = open(fichier,"r",)
        g = open (fichier[:-4]+"-complet.tex","w")
        for i in f.readlines():
            if i[:6]=="\input":
                k=i[8:-3]
                h=open(k,"r")
                contenu=h.read()
                g.write(contenu)
                h.close()
            else:
                g.write(i)
        g.close()       
        f.close()
        champ_label = Label(Mafenetre, text="Fichier "+fichier+" fait !")
        champ_label.pack()
    except:
        champ_label=Label(Mafenetre, text="Pas réussi !")
        champ_label.pack()
   
   
   
   
def Ouvrir():
   
    fichier = tkinter.filedialog.askopenfilename(title="Ouvrir un fichier",filetypes=[("fichiers latex",".tex"),("tous les fichiers",".*")])
    Complete(fichier)

def Ouvrir_rep():
    rep = tkinter.filedialog.askdirectory(title="Choisissez un répertoire")
    for fichier in os.listdir(rep):
        if fichier[-4:].lower() == ".tex":
            try:
                Complete(fichier)
            except:
                champ_label=Label(Mafenetre, text="Pas réussi !")
                champ_label.pack()

# Programme principal
Mafenetre = Tk()
Mafenetre.title("Fusionner fichiers LateX")
     
# Création de la fenêtre
Mafenetre.message = Label(Mafenetre, text="Fusionner un fichier ou tous les fichiers d'un répertoire ?")
Mafenetre.message.pack()

Mafenetre.bouton_fichier = Button(Mafenetre, text="Ouvrir fichier",command=Ouvrir)
Mafenetre.bouton_fichier.pack()

Mafenetre.bouton_rep = Button(Mafenetre, text="Ouvrir un répertoire", command=Ouvrir_rep)
Mafenetre.bouton_rep.pack()

Mafenetre.bouton_quitter = Button(Mafenetre, text="Quitter", command=Mafenetre.destroy)
Mafenetre.bouton_quitter.pack()


# Afficher la fenêtre

Mafenetre.mainloop()
Nollan
Déca-utilisateur
 
Messages: 10
Inscription: Lundi 14 Mai 2007, 17:33

Re: [Résolu] Fusion de documents LateX

Messagepar marco56 » Dimanche 21 Décembre 2014, 19:37

Impressionnant !
Je suis vraiment épaté et je retire tout ce que j'ai dit dans mon premier post :mrgreen:
Félicitations et effectivement, ce serait dommage de s'arrêter là, vu ta facilité à apprendre Python.
marco56
Giga-utilisateur
 
Messages: 759
Inscription: Jeudi 25 Novembre 2010, 22:10
Statut actuel: Actif et salarié | Enseignant

Re: [Résolu] Fusion de documents LateX

Messagepar marco56 » Dimanche 21 Décembre 2014, 19:45

Quelques idées en plus, pour améliorer éventuellement ton script.

Code: Tout sélectionner

import tkinter as tk
 
class Widget(tk.Frame):
 
    def __init__(self, parent=None, names=None):
        super().__init__(parent)
        self._create_widget()
        if names:
            self._populate(names)
 
    def _create_widget(self):
 
        self._left = left = tk.Listbox(self, selectmode='extended')
        left.grid(row=0, column=0)
 
        self._right = right = tk.Listbox(self, selectmode='extended')
        right.grid(row=0, column=2)
 
        middle = tk.Frame(self)
        middle.grid(row=0, column=1)
 
        def move_all(src, dst):
            def _cb_():
                for s in src.get(0,'end'):
                    dst.insert('end', s)
                src.delete(0,'end')
            return _cb_
 
        def move_selected(src, dst):
            def _cb_():
                for shift, x in enumerate(
                    [ int(_) for _ in src.curselection() ]):
                    ix = x - shift
                    s = src.get(ix)
                    dst.insert('end', s)
                    src.delete(ix)
            return _cb_
 
        defs = [
            { 'text': '>>', 'command' : move_all(left, right) },
            { 'text': '>',  'command' : move_selected(left, right), },
            { 'text': '<<', 'command' : move_all(right, left), },
            { 'text': '<',  'command' : move_selected(right, left), },
        ]
        for kwds in defs: tk.Button(middle, kwds).pack()
 
    def _populate(self, names):
        left = self._left
        for s in names:
            left.insert('end', s)
 
if __name__ == '__main__':
    root = tk.Tk()
    widget = Widget(root, ('aa', 'bb', 'cc'))
    widget.pack()
    tk.mainloop()
marco56
Giga-utilisateur
 
Messages: 759
Inscription: Jeudi 25 Novembre 2010, 22:10
Statut actuel: Actif et salarié | Enseignant

Re: [Résolu] Fusion de documents LateX

Messagepar Nollan » Dimanche 21 Décembre 2014, 21:18

:lol:

Je n'ai pas vraiment de mérite: Google + des tutos bien faits :D

Et puis je pratique LateX depuis quelques années, plus des restes d'informatique datant de mes études: Pascal (Les pointeurs, que du bonheur !!!), Lisp (à la recherche de la parenthèse perdue), et un peu de bidouille Java et HTML. Et bien sûr Linux.
Bref, ça aide à apprendre un nouveau langage.
Surtout que Python, ça faisait longtemps que je voulais m'y mettre.

J'ai un peu amélioré mon code:
- J'ai fait un test pour savoir si le fichier était déjà "fusionné", en gros si il restait un "\input{". Sinon je me retrouvais avec des "fichier-complet", "fichier-complet-complet", "fichier-complet-complet-....-complet" !!!
- Et un test d'arrêt à "\begin{document}" pour éviter de se retrouver avec du code parasite quand on insère un fichier de macro, genre "tabvar" de "PStPLus".

Pour ton code:
Je ne suis pas assez avancé en Python pour bien le comprendre, mais ça va venir :D
En gros tu crées une classe pour les widgets.
Ce code s'insère tel quel dans mon fichier .py ou je dois adapter deux trois trucs ?
Nollan
Déca-utilisateur
 
Messages: 10
Inscription: Lundi 14 Mai 2007, 17:33

Re: [Résolu] Fusion de documents LateX

Messagepar marco56 » Dimanche 21 Décembre 2014, 22:29

Désolé, mais je ne vais pas pouvoir t'aider.
J'enseigne python depuis un an et demi mais je n'ai pas eu le temps de me mettre à tkinter.
Pour l'instant, je gère l'urgence : les nouveaux programmes de cpge.
L'info est hyper chronophage et je verrais tkinter l'année prochaine.
Le code que je t'ai fourni provient de la toile.
Bravo encore à toi !
marco56
Giga-utilisateur
 
Messages: 759
Inscription: Jeudi 25 Novembre 2010, 22:10
Statut actuel: Actif et salarié | Enseignant

Re: [Résolu] Fusion de documents LateX

Messagepar Nollan » Lundi 22 Décembre 2014, 11:16

Bonjour,

Sans vouloir transformer le sujet en troll:

J'ai fait un script qui remplace les
Code: Tout sélectionner
"$$"
par des
Code: Tout sélectionner
"\[   \]"
. Par exemple
Code: Tout sélectionner
$$f(x)=3x$$
est remplacé par
Code: Tout sélectionner
\[ f(x)=3x \]
ce qui est préférable :D
Code: Tout sélectionner
# script remplacer les $$ par \[ \]
from tkinter import *
import tkinter.messagebox
import tkinter.filedialog
import os


def Remplace_double_dollard(fichier):
    try:
        f = open(fichier,"r",)
        contenu_global=f.read()
        f.close()
        g=contenu_global.find("$$")
        contenu=""
        debut=0
        while g != -1:
            d=contenu_global.find("$$",g+2)
            contenu=contenu+contenu_global[debut:g]+"\["+contenu_global[g+2:d]+"\]"
            debut=d+2
            g=contenu_global.find("$$",debut)
        contenu=contenu+contenu_global[debut:-1]
        s=open(fichier,"w")
        s.write(contenu)
        s.close()
        champ_label=Label(Mafenetre, text=fichier+" Fait")
        champ_label.pack()
       
           
    except:
        champ_label=Label(Mafenetre, text="Pas réussi")
        champ_label.pack()
   
   
   
   
def Ouvrir():
   
    fichier = tkinter.filedialog.askopenfilename(title="Ouvrir un fichier",filetypes=[("fichiers latex",".tex"),("tous les fichiers",".*")])
    Remplace_double_dollard(fichier)

def Ouvrir_rep():
    rep = tkinter.filedialog.askdirectory(title="Choisissez un répertoire")
    for fichier in os.listdir(rep):
        if fichier[-4:].lower() == ".tex":
            try:
                Remplace_double_dollard(fichier)
            except:
                champ_label=Label(Mafenetre, text="Pas réussi")
                champ_label.pack()

# Programme principal
Mafenetre = Tk()
Mafenetre.title("Remplacer les $$ par des \[...\]")
     
# Création de la fenêtre
Mafenetre.message = Label(Mafenetre, text="Agir sur un fichier ou sur un répertoire ?")
Mafenetre.message.pack()

Mafenetre.bouton_fichier = Button(Mafenetre, text="Ouvrir fichier",command=Ouvrir)
Mafenetre.bouton_fichier.pack()

Mafenetre.bouton_rep = Button(Mafenetre, text="Ouvrir un répertoire", command=Ouvrir_rep)
Mafenetre.bouton_rep.pack()

Mafenetre.bouton_quitter = Button(Mafenetre, text="Quitter", command=Mafenetre.destroy)
Mafenetre.bouton_quitter.pack()


# Afficher la fenêtre

Mafenetre.mainloop()


Je teste en ce moment des insertions de calcul formel. J'ai fait une résolution automatique de ax²+bx+c=0 avec rédaction. Je sais, ça a déjà été fait, mais c'est pour bien apprendre à manipuler.

Bref, c'est chronophage, mais c'est investissement en temps qui permettra d'aller beaucoup plus vite plus tard.
Nollan
Déca-utilisateur
 
Messages: 10
Inscription: Lundi 14 Mai 2007, 17:33

Re: [Résolu] Fusion de documents LateX

Messagepar marco56 » Lundi 22 Décembre 2014, 14:39

Nollan a écrit:Bref, c'est chronophage, mais c'est investissement en temps qui permettra d'aller beaucoup plus vite plus tard.

Oui, on gagne beaucoup de temps avec l'informatique à faire des choses que l'on ne faisait pas avant.
Tiens-nous au courant.
Si cela t'intéresse, on peut créer un fil LaTeX et Python : l'année dernière, j'avais écrit des scripts :
un fichier python permettait de lancer une compilation.
D'un autre côté, j'avais un fichier tex qui lançait un script python et qui récupérait les résultats ainsi que les figures. Pas grand intérêt en fait mais bon, c'était pour le fun.
marco56
Giga-utilisateur
 
Messages: 759
Inscription: Jeudi 25 Novembre 2010, 22:10
Statut actuel: Actif et salarié | Enseignant

Re: [Résolu] Fusion de documents LateX

Messagepar gigiair » Lundi 22 Décembre 2014, 22:08

Je ne connais pas du tout Python, mais je me demande si ton fichier source contient la déclaration

Code: Tout sélectionner
%Ici début de la ligne
   \input{monfichier.tex}   %

Ton code fera-t-il le travail attendu ? (avec les caractères espace en début de ligne et à la fin, le % étant facultatif)

Pour le peu que je connais de Python, il y a aussi des expressions régulières.
JJR.
LaTeXien migrateur.
gigiair
Exa-utilisateur
 
Messages: 2399
Inscription: Samedi 08 Juillet 2006, 19:56
Localisation: Saint Bonnet Elvert
Statut actuel: Actif et salarié


Retourner vers LaTeX

 


  • Articles en relation
    Réponses
    Vus
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum: Google [Bot], Grapeshot [Crawler], kamel, Magpie [Crawler], Yandex [Bot] et 20 invités