From f0e9585f5e47401746e78b8b939078d80a848120 Mon Sep 17 00:00:00 2001 From: "wulf@coulmann.de" Date: Thu, 13 Jan 2011 18:39:08 +0100 Subject: [PATCH] fancy LaTeX initial siehe doc/2011-12-14_alternatives_vorlagensystem_f-tex.txt --- ...2-14_alternatives_vorlagensystem_f-tex.txt | 245 ++++ doc/changelog | 7 + templates/f-tex/letter.tex | 563 +++++++++ templates/f-tex/mydata.tex.example | 21 + templates/f-tex/sample.lco | 142 +++ templates/f-tex/sample_head.pdf | Bin 0 -> 73601 bytes templates/f-tex/setup.sh | 1082 +++++++++++++++++ templates/f-tex/translations.tex | 198 +++ templates/f-tex/xstring.sty | 704 +++++++++++ templates/f-tex/zwischensumme.sty | 228 ++++ 10 files changed, 3190 insertions(+) create mode 100644 doc/2011-12-14_alternatives_vorlagensystem_f-tex.txt create mode 100644 templates/f-tex/letter.tex create mode 100644 templates/f-tex/mydata.tex.example create mode 100644 templates/f-tex/sample.lco create mode 100644 templates/f-tex/sample_head.pdf create mode 100755 templates/f-tex/setup.sh create mode 100644 templates/f-tex/translations.tex create mode 100644 templates/f-tex/xstring.sty create mode 100644 templates/f-tex/zwischensumme.sty diff --git a/doc/2011-12-14_alternatives_vorlagensystem_f-tex.txt b/doc/2011-12-14_alternatives_vorlagensystem_f-tex.txt new file mode 100644 index 000000000..d4c5b4f3d --- /dev/null +++ b/doc/2011-12-14_alternatives_vorlagensystem_f-tex.txt @@ -0,0 +1,245 @@ +README lx-office Fancy-LaTeX (f-tex) + +# Revision 1.0-u (16.11.2011) +# Revision 0.9 (13.11.2011) +# Revision 0.8 (12.09.2011) +# Revision 0.7 (12.07.2011) +# Revision 0.6 (16.06.2011) +# Revision 0.5 (15.04.2011) +# Revision 0.4 (14.02.2011) +# Revision 0.3 (03.01.2011) +# Revision 0.2 (24.12.2010) +# Revision 0.1 (03.11.2009) + + +# Einleitung + + Es gibt ein alternatives LaTeX Vorlagensystem im Verzeichnis + templates/f-tex + Fuer das Einrichten der Vorlagen gibt es ein Setup-Script + + +# Voraussetzung: + + - funktionierende Lx-Office Intallation + - mindestens eine Mandantendatenbank + weiter ist es hilfreich: + - mindestens einen Benutzer mit Verweis auf ein Vorlagenverzeichs + - Bereits angelegte Sprachkuerzel, wenn mehrsprachige Dokumente erstellt + werden sollen. + +# Feature Uebersicht + + - einfach Nutzung durch mitgeliefertes Setup-Script + - Keine Retundanz. Es wird ein und die selbe Latex-Vorlage fuer alle + briefartigen Dokumente verwendet. Also Angebot, Rechnung, + Performarechnung, Lieferschein, aber eben nicht fuer Paketaufkleber + etc.. + - Leichte Anpassung an das Firmen Layout durch verwendung eines Hintergrund-PDF + dieses kann leicht mit dem eigenen Lieblingsprogramm erstellt werden + (Openoffice, Inkscape, Gimp, Adobe*) + - Hintergrundpdf um schaltbar auf "nur erste Seite" (default) oder "alle Seiten" + (option "bgPdfFirstPageOnly" in Datei letter.lco) + - Hintergrundpdf fuer Ausdruck auf bereits bedrucktem Briefpapier Abschaltbar, + es wird dann nur bei per email versendeten Dokumenten eingebunden. + (Option "bgPdfEmailOnly" in Datei letter.lco) + - Nutzung der Layout-Funktionen von Latex fuer Seitenumbruch, + wiederholung von Kopfzeilen, Zwischensummen etc. (danke an Kai-Martin fuer + die Vorarbeit) + - Anzeige des Empfaengerlandes im Adressfeld nur, wenn es vom Land des + eigenen Unternehmens abweicht (also die Rechnung das Land verlaesst). + - Multisprachfaehig leicht um weitere Sprachen zu erweitern, alle + Übersetzungen in der Datei translatinos.tex. + - Auflistung von Bruttopreisen fuer Endverbraucher. + + + + +# die Installation + + Wenn es noch keine LaTeX installation gibt, installiere die folgenden Pakete + (Debian) + aptitude install \ + texlive-base-bin \ + texlive-latex-recommended \ + texlive-fonts-recommended \ + texlive-latex-extra \ + texlive-lang-german \ + texlive-generic-extra + (Info fuer != Debian Installationen: die Abhaengigkeiten werden waehrend des + Setups nochmals geprueft) + + Rufe das folgende Script auf: + [lxo-home]/templates/f-tex/setup.sh + und folge den Anweisungen. + + Erstelle eine pdf-Hintergrund Datei und verlinke sie nach ./letter_head.pdf + + Editiere den Bereich "settings" in der datei letter.lco "" + + # oder etwas Detaillierter: + Es wird eine Datei sample.lco erstellt und diese nach letter.lco verlinkt. + Eigentlich ist dies die Datei die fuer die Firmenspezifischen Anpassungen + gedacht ist. Da die Einstiegshuerde in LaTeX nicht ganz niedrig ist, wird in + dieser Datei auf ein Hintergrundpdf verwiesen. Ich empfehle ueber dieses pdf + die persoenlichen Layoutanpassungen vorzunehmen und sample.lco unveraendert zu + lassen. Die die Anpassung ueber eine *.lco Datei die letztlich auf letter.lco + verlinkt ist ist aber auch moeglich. + + Es wird eine Datei sample_head.pdf mit ausgeliefert, diese wird nach + letter_head.pdf verlinkt. Damit gibt es schon mal eine Funktionsfaehige + Vorlage. Schau Dir nach Abschluss der Installation die Datei sample_haed.pdf + an und erstelle ein entsprechendes pdf passend zum Briefkopf Deiner Firma, + diese dann im Template Verzeichniss ablegen und statt sample_head.pdf nach + letter_head.pdf verlinken. + + per default erstellt das Setupscript einen symbolischen Link + ./sample_head.pdf -> ./letter_head.pdf + letzlich muss ./letter_head.pdf auf das passende Hintergrundpdf verweisen, + welches gewuenschten Briefkopf enthaelt. Bei Updates oder nach erneutem + Aufruf des setup Scripts werden bestehende Links nicht ohne Rueckfrage + ersetzt, wer also schon seinen Briefkopf verlinkt hat, braucht diesen Link + nicht immer wieder neu anlegen. Das gleiche Prinzip gilt fuer letter.lco. + + Es wird eine Datei mydata.tex erstellt, sie ist mit der aus + lp (Label Print in erp) kompatibel. Diese braucht man also nur einmal + fuer jedes template Verzeichnis zu generieren. + Bei Formatierungsschwierigkeiten bitte mit + [lxo-home]/templates/f-tex/mydata.tex.example vergleichen. + + Alle Anpassungen zum Briefkopf, Fusszeilen, Firmenlogos, etc. + sollten ueber die Hintergrund pdf datei oder die *.lco Datei erfolgen. + + +# einheitliche Latex-Vorlagen -- Background + + Das Konzept von lx-office sieht vor, fuer jedes Dokument + (Auftragsbestaetigung, Lieferschein, Rechnung, etc.) eine + Latex-Vorlage vorzuhalten, dies ist sehr Wartungsunfreundlich. Auch + das Einlesen einer einheitlichen Quelle fuer den Briefkopf bringt nur + bedingte Vorteile, da hier leicht die Pflege der Artikel-Tabellen aus + dem Ruder laeuft. Bei dem vorliegenden Ansatz wird fuer alle + Briefartigen Dokumente mit Artikel-Tabellen eine einheitliche + Latexvorlage verwendet, welche ueber Codeweichen die Besonderheiten + der jeweiligen Dokumente Beruecksichtigt + - Tabellen mit oder ohne Preis + - Sprache der Tabellenueberschriften etc. + - Anpassung der Bezugs-Zeile (z.B. Rechnungsnummer versus + Angebotsnummer) + - Darstellung von Brutto oder Netto-Preisen in der Auflistung + (Endverbraucher versus Gewerblicher Kunde) + Dies laesst sich in lx-office nur ueber einen Kunstgriff realisieren, + da zum einen die perl-Anwendung nach latex-Vorlagen mit bestimmten + Namen sucht (z.B. sales_order_de.tex fuer die deutschsprachige + Auftragsbestaetigung -- wenn deutsch mit dem Vorlagenkuerzel de + angelegt wurde) und zum Anderen die Information um welches Dokument es + sich handelt nicht direkt innerhalb von Latex zur Verfuegung steht. + + Umgesetzt wurde dies hier nun ueber symbolische Links im Dateisystem. Es + gibt also eine Vorlage letter.tex (die ihrerseits weitere tex-Dateien + einbindet) und fuer jeden Dokumenttyp der durch letter.tex abgedeckt on von + jedem dieser wiederum in jeder verfuegbaren Sprache legt das setup Script einen + link in der lx-office Namenskonvention an, der auf die Datei letter.tex + verweist. Die Datei letter.tex wertet den Namen der Aufgerufenen Datei aus und + passt ihre Ausgabe dementsprechend an. Wenn zum Beispiel lx-office die Datei + packing_list_de.tex aufruft (die ja nur ein Link nach letter.tex ist) liegt die + Information des aktuellen Dokumentnamen (packing_list_de.tex) vor und latex + weiss, keine Preise, Lieferscheinnummer anzeigen, deutsche sprachumgebung, usw. + + Es liegt mit der Datei setup.sh ein script vor, welches die Abhaengigkeiten + im System prueft und die benotigten Dateien und symbolischen Links erstellt. + Das script ist so aufgebaut, dass es bei Updates auch auf bestehende f-tex + Vorlagenordner angewendet werden kann, ohne vorhandene Personalisierungen zu + ueberschreiben. Die Benoetigten Informationen wie Template-Verzeichniss, + vorhandene Sprachkuerzel, etc werden waerend des setupprozesses abgefragt. Der + Setupprozess kann also sooft wie benoetigt wiederholt werden, auch wenn bereits + ein templateverzeichniss existiert. + + + Nachteil: + Ja, alles hat seinen Preis ... + Latex hat ohnehin eine sehr steile Lehrnkurve. Die Datei letter.tex + ist sehr komplex und verstaerkt damit diesen Effekt noch einmal erheblich. + Wer Latex-Erfahrung hat, oder geuebt ist Scriptsparachen nachzuvollziehen kann + natuerlich auch innerhalb der Tabellendarstellung gut persoenliche Anpassungen + vornehmen. Aber man kann sich hier bei Veraenderungen sehr schnell haeftig in + den Fuss schiessen. + Wer nicht so tief in die Materie einsteigen will oder leicht zu + frustrieren ist, sollte sein Hintergrund PDF auf Basis der mitglieferten + Datei sample_head.pdf erstellen, und sich an der Form der dargestellten Tabellen + wie sie ausgeliefert werden, erfreuen. + Kleiner Tipp: + + Nicht zu viel auf einmal wollen, lieber kleine kontinuierliche + Schritte gehen. + + Alternativ kann man sich natuerlich fuer die Latex-Vorlagen + professionelle Hilfe hohlen. + + +Bruttopreise fuer Endvorbraucher + Der auszuweisende Bruttopreis wird innerhalb der LaTeX Umgebung berechnet. + + - Background: + es gibt zwar ein Feld um bei Auftraegen "alle Preise Brutto" auszuwaehlen, + aber: + - hierfuer muessen die Preise auch in Brutto in der Datenbank stehen + (ja -- das laesst sich ueber die Preisgruppen und die Zuordung einer Default-Preisgruppe + handhaben) + - man darf beim Anlegen des Vorgangs nicht vergessen Dieses Haekchen zu setzen. + (das ist in der Praxis wenn man sowohl Endverbraucher- wie Gewerbekunden beliefert + der eigentliche Knackpunkt) + + Es gibt mit f-tex eine weitere Alternative. Die Information ob Brutto oder + Nettorechnung wird mit den Zahlarten verknuepft. Zahlarten bei denen + Rechnungen, Angebote, etc, in Brutto ausgegeben werden sollen enden mit "_E" + (fuer Endverbraucher) Falls identische Zahlarten fuer Gewerbekunden und + Endverbraucher vorhanden sind legt man diese einfach doppelt an (einmal mit + der Namensendung "_E") + - Gewinn: + - die Entscheidung ob Netopreise ausgewiesen werden ist nicht mehr fix + mit einer Preisliste Verbunden. + - die Default-Zahlart kann im Kundendatensatz hinterlegt werden und man + muss nicht mehr daran denken "alle Preise Netto" auszuwaehlen. + - Die Entscheidung ob Netto/Oder Bruttopreise ausgewiesen werden kann direkt + beim Drucken reviediert werden, ohne dass sich der Auftragswert aendert. + +Lieferadressen + + - in Lieferscheinen kommen shipto* -Variablen im Adressfeld zum Einsatz + - wenn die shipto*variable leer ist wird die entsprechende + Adressvariable eingesetzt. Wenn Also die Lieferadresse in Strasse, + Hausnummer und Ort abweicht, muessen auch nur diese Felder in der + Lieferadresse ausgefuellt werden. Fuer den Firmenname wird der Wert der + Hauptadresse angezeigt. + +Troubleshooting -- Fehler suchen: + Wenn sich das Problem nicht auf Grund der ausgabe im Webbrowser verifizieren laesst: + + editiere [flxo-home]/config/lx_office.conf und aendere "keep_tmp_files" auf 1 + keep_temp_files = 1; + + bei fastcgi oder mod_perl den Webserver neu Starten + + Nochmal einen Druckversuch im Webfrontend ausloesen + + wechsele in das users Verzeichnis von lxo + cd [lxo-home]/users + + LaTeX Suchpfad anpassen: + export TEXINPUTS=".:[lxo-home]/templates/[aktuelles_template_verzeichniss]:" + + Finde herraus welche datei lxo beim letzten Durchlauf erstellt hat + ls -lahtr ./1*.tex + Es sollte die letzte Datei ganz unten sein + + fuer besseren Hinweis auf Fehler texdatei nochmals uebersetzen + pdflatex ./1*.tex + + in der *.tex datei nach dem Fehler suchen. + +Changelogeintrag fuer offiziellen tree: + Kleine Verbesserungen: + Zusaetzliches alternatives LaTeX Templatesystem + + diff --git a/doc/changelog b/doc/changelog index 7fb438619..918667df7 100644 --- a/doc/changelog +++ b/doc/changelog @@ -2,6 +2,13 @@ # Veränderungen von Lx-Office ERP # ################################### +- Alternatives Vorlagenstemsystem f-tex + * Setup Script + * mehrsprachig + * leichte Integration des Firmenbriefkopfs + * Ausgabe von Bruttopreisen in den Positionen fuer Endverbraucher moeglich + siehe doc/2011-12-14_alternatives_vorlagensystem_f-tex.txt + - Ein neuer Vorlagensatz RB kam hinzu, der einige Ideen aufgreift, die in folgendem Vortrag erwähnt wurden: http://www.lx-office.org/uploads/media/Lx-Office_Anwendertreffen_LaTeX-Druckvorlagen-31.01.2011_01.pdf diff --git a/templates/f-tex/letter.tex b/templates/f-tex/letter.tex new file mode 100644 index 000000000..726f5fddf --- /dev/null +++ b/templates/f-tex/letter.tex @@ -0,0 +1,563 @@ +% ---------------------------------------------------------- +% letter.tex +% Globale Vorlage fuer Briefartige Documente LX-Office 2.6 +% +% Changelog: see gitlog + \newcommand{\ftLetterVersion}{1.0-u (16.11.2011)} +% +% Lizenz +% http://www.gnu.de/licenses/gpl-3.0.html +% +% Siehe ./README +% +% Autor: Wulf Coulmann scripts_at_gpl.coulmann.de +% Aufgebaut auf invoice.tex 0.1 kmk@lilalaser.de +% +% ---------------------------------------------------------- + +\documentclass[letter,fontsize=11pt]{scrlttr2} + + +\begingroup + \makeatletter + \@latex@warning@no@line{ #### this is letter.tex \ftLetterVersion #####} +\endgroup + + +\usepackage{ifpdf} +\usepackage{graphicx} +\usepackage{german} +\usepackage{textcomp} +\usepackage{lastpage} +\usepackage{filecontents} +\usepackage{etex} +\usepackage{ltxtable} +\usepackage{tabularx} +\usepackage{longtable} +\usepackage{booktabs} +\usepackage{numprint} +\usepackage{xstring} +\newcommand{\leer}{} +\usepackage{zwischensumme} +\ifthenelse{\isundefined{\employeecountry}}{\input{mydata}}{} + + + +% Dateinamen einlesen und auswertbar machen +\scantokens\expandafter{% + \expandafter\def\expandafter\docname\expandafter{\jobname}} + +%%%%%%%%% Report-Variablen umsetzen, damit latex sie in lxbriefkopf.tex sieht. +%%%% Die eigenen Daten +\newcommand{\employeename}{<%employee_name%>} +\newcommand{\employeecompany}{<%employee_company%>} +\newcommand{\employeeaddress}{<%employee_address%>} +\newcommand{\employeetel}{<%employee_tel%>} +\newcommand{\employeefax}{<%employee_fax%>} +\newcommand{\employeecoustid}{<%employee_co_ustid%>} +\newcommand{\employeetaxnumber}{<%employee_taxnumber%>} +\newcommand{\media}{<%media%>} + + +%%%% Adressat +\newcommand{\name}{<%name%>} +\newcommand{\Shipname}{\ifthenelse{\equal{<%shiptoname%>}{\leer}}{<%name%>}{<%shiptoname%>}} +\newcommand{\departmentone}{<%department_1%>} +\newcommand{\departmenttwo}{<%department_2%>} +\newcommand{\cpgreeting}{<%cp_greeting%>} +\newcommand{\cptitle}{<%cp_title%>} +\newcommand{\cpgivenname}{<%cp_givenname%>} +\newcommand{\cpname}{<%cp_name%>} +\newcommand{\street}{<%street%>} +\newcommand{\Shipstreet}{\ifthenelse{\equal{<%shiptostreet%>}{\leer}}{<%street%>}{<%shiptostreet%>}} +\newcommand{\country}{<%country%>} +\newcommand{\Shipcountry}{\ifthenelse{\equal{<%shiptocountry%>}{\leer}}{<%country%>}{<%shiptocountry%>}} +\newcommand{\UstId}{<%ustid%>} +\newcommand{\zipcode}{<%zipcode%>} +\newcommand{\Shipzipcode}{\ifthenelse{\equal{<%shiptozipcode%>}{\leer}}{<%zipcode%>}{<%shiptozipcode%>}} +\newcommand{\city}{<%city%>} +\newcommand{\Shipcity}{\ifthenelse{\equal{<%shiptocity%>}{\leer}}{<%city%>}{<%shiptocity%>}} +\newcommand{\phone}{<%customerphone%>} +\newcommand{\fax}{<%customerfax%>} + +%%%% Variablen, die sich auf das ganze Dokument beziehen +\newcommand{\kundennummer}{<%customernumber%>} +\newcommand{\vendornumber}{<%vendornumber%>} +\newcommand{\quonumber}{<%quonumber%>} % Angebotsnummer +\newcommand{\ordnumber}{<%ordnumber%>} % Auftragsnummer bei uns +\newcommand{\cusordnumber}{<%cusordnumber%>} % Auftragsnummer beim Kunden +\newcommand{\invnumber}{<%invnumber%>} % Rechnungsnummer +\newcommand{\donumber}{<%donumber%>} % Lieferscheinnummer +%\newcommand{\docnumber}{Rechnungsnummer: \invnumber} +\newcommand{\quodate}{<%quodate%>} % Angebotsdatum +\newcommand{\orddate}{<%orddate%>} % Auftragsdatum +\newcommand{\reqdate}{<%reqdate%>} % gewuenschtes Lieferdatum +\newcommand{\deliverydate}{<%deliverydate%>} % Lieferdatum +\newcommand{\invdate}{<%invdate%>} % Rechnungsdatum +\newcommand{\transdate}{<%transdate%>} % Lieferscheindatum +\newcommand{\terms}{<%terms%>} % Zahlungsfrist +\newcommand{\duedate}{<%duedate%>} % Fälligkeitsdatum +\newcommand{\invtotal}{<%invtotal%>} % Gesamtbetrag +\newcommand{\paid}{<%paid%>} % Schon bezahlt +\newcommand{\total}{<%total%>} % Restbetrag +\newcommand{\subtotal}{<%subtotal NOFORMAT%>} % Restbetrag +\newcommand{\paymentterms}{<%payment_terms%>} % Zahlungsbedingungen +\newcommand{\paymentPrivatEnd}{E} % Endung bei Privatkunden +\newcommand{\paymenttype}{<%payment_description%>} % name der Zahlungs-art - fuer Steuerung brutto/netto + + +%%%% Lieferadresse +\newcommand{\shiptoname}{<%shiptoname%>} +\newcommand{\shiptocontact}{<%shiptocontact%>} +\newcommand{\shiptodepartmentone}{<%shiptodepartment_1%>} +\newcommand{\shiptodepartmenttwo}{<%shiptodepartment_2%>} +\newcommand{\shiptostreet}{<%shiptostreet%>} +\newcommand{\shiptocity}{<%shiptocity%>} +\newcommand{\shiptocountry}{<%shiptocountry%>} +\newcommand{\shiptophone}{<%shiptophone%>} +\newcommand{\shiptozipcode}{<%shiptozipcode%>} +\newcommand{\shiptofax}{<%shiptofax%>} + +%%%% Die Waehrungsvariable in Waehrunszeichen umsetzen +\newcommand{\currency}{<%currency%>} +\ifthenelse{\equal{\currency}{EUR}}{\let\currency\euro}{} +\ifthenelse{\equal{\currency}{YEN}}{\let\currency\textyen}{} +\ifthenelse{\equal{\currency}{GBP}}{\let\currency\pounds}{} +\ifthenelse{\equal{\currency}{USD}}{\let\currency\$}{} + +%%%%%%%%%%%%% Ende Reportvariablen-Umsetzung + +\newcommand{\NoValue}{0} +\newcommand{\Picklist}{0} +\newcommand{\PurchaseOrder}{0} +\newcommand{\trash}{0} +\newcommand{\nonemptyline}[2]{\ifthenelse{\equal{#2}{\leer}}{}{#1#2~\\}} +\newcommand{\MyAdress}{\IfSubStr{\docname}{sales_delivery_order}{\Shipname~\\ + % lieferadresse wenn Lieferschein + \nonemptyline{\cpgreeting{ }\cpgivenname{ }}{\cpname} + \nonemptyline{}{\departmentone} + \Shipstreet ~\\ + \Shipzipcode{ }\Shipcity + \ifthenelse{\equal{\Shipcountry}{\employeecountry}}{}{ + \ifthenelse{\equal{\Shipcountry}{\leer}}{}{ ~\\ \Shipcountry} } % Laenderangabe wird nur gedruckt, + ~ % wenn der Empfaenger nicht im eigenen Land sitzt. + }{ + \name~\\ + \nonemptyline{\cpgreeting{ }\cpgivenname{ }}{\cpname} + \nonemptyline{}{\departmentone} + \street ~\\ + \zipcode{ }\city + \ifthenelse{\equal{\country} {\employeecountry}}{}{ + \ifthenelse{\equal{\country}{\leer}}{}{ ~\\ \country} } % Laenderangabe wird nur gedruckt, + ~ % wenn der Empfaenger nicht im eigenen Land sitzt. + } +} + + + +\begin{document} + +%%% dei folgenden Funktionen lesen den Dokumentennamen aus und _muessen_nach_ \begin{dokument} stehen. + +% ==== statische Begriffe in der aktuellen Sprache einlesen +\input{translations} + + +\ifthenelse{\bgPdfEmailOnly = 1 }{ + \ifthenelse{\equal{\media}{email}}{ + }{ + \firsthead{} + \watermark{} + } +}{} + + +% ==== dokumenttyp ermitteln +\IfSubStr{\docname}{pick_list}{ + % Sammelliste + \setkomavar{backaddress}{\DeliveryAddress} + \firsthead{ + \hspace{-3mm} + \resizebox{\useplength{firstheadwidth}-50mm}{!}{% + \huge \TitlePicklist + } + } + \renewcommand{\NoValue}{1} + \renewcommand{\Picklist}{1} + \newcommand{\doctype}{} + \newcommand{\MyDocdate}{\transdate} + \newcommand{\DocNoTitle}{\DelorderNumber} + \newcommand{\docnumber}{\donumber} + \renewcommand{\deliverydate}{\transdate} + % 2. Documentnummer + \ifthenelse{\equal{\ordnumber}{\leer}}{ + % wenn keine Auftragsnummer -> Angebotsnummer + \newcommand{\SecNoTitle}{\QuotationNumber} + \newcommand{\secnumber}{\quonumber} + }{ + \newcommand{\SecNoTitle}{\OrderNumber} + \newcommand{\secnumber}{\ordnumber} + } +}{} +\IfSubStr{\docname}{sales_delivery_order}{ + % Lieferschein + \renewcommand{\NoValue}{1} + \newcommand{\doctype}{\TitleDelorder} + \newcommand{\MyDocdate}{\transdate} + \newcommand{\DocNoTitle}{\DelorderNumber} + \newcommand{\docnumber}{\donumber} + \renewcommand{\deliverydate}{\transdate} + % 2. Documentnummer + \ifthenelse{\equal{\ordnumber}{\leer}}{ + % wenn keine Auftragsnummer -> Angebotsnummer + \newcommand{\SecNoTitle}{\QuotationNumber} + \newcommand{\secnumber}{\quonumber} + }{ + \newcommand{\SecNoTitle}{\OrderNumber} + \newcommand{\secnumber}{\ordnumber} + } +}{} +\IfSubStr{\docname}{invoice}{ + % Rechnung + \newcommand{\doctype}{\TitleInv} + \newcommand{\MyDocdate}{\invdate} + \newcommand{\DocNoTitle}{\InvNumber} + \newcommand{\docnumber}{\invnumber} + % 2. Documentnummer + \ifthenelse{\equal{\ordnumber}{\leer}}{ + % wenn keine Auftragsnummer -> Angebotsnummer + \newcommand{\SecNoTitle}{\QuotationNumber} + \newcommand{\secnumber}{\quonumber} + }{ + \newcommand{\SecNoTitle}{\OrderNumber} + \newcommand{\secnumber}{\ordnumber} + } +}{} +\IfSubStr{\docname}{proforma}{ + \newcommand{\doctype}{\TitleProforma} + \newcommand{\MyDocdate}{\invdate} + \newcommand{\DocNoTitle}{\InvNumber} + \newcommand{\docnumber}{\invnumber} + % 2. Documentnummer + \ifthenelse{\equal{\ordnumber}{\leer}}{ + % wenn keine Auftragsnummer -> Angebotsnummer + \newcommand{\SecNoTitle}{\QuotationNumber} + \newcommand{\secnumber}{\quonumber} + }{ + \newcommand{\SecNoTitle}{\OrderNumber} + \newcommand{\secnumber}{\ordnumber} + } +}{} +\IfSubStr{\docname}{purchase_order}{ + \renewcommand{\PurchaseOrder}{1} + \newcommand{\doctype}{\TitlePurchaseOrder} + \newcommand{\MyDocdate}{\orddate} + \newcommand{\DocNoTitle}{\RequestOrderNumber} + \newcommand{\docnumber}{\ordnumber} + \renewcommand{\deliverydate}{\reqdate} + \renewcommand{\DelDate}{\ReqByTitle} + \renewcommand{\CustomerID}{\VendorID} + \renewcommand{\kundennummer}{\vendornumber} + \newcommand{\SecNoTitle}{} + \newcommand{\secnumber}{} +}{} +\IfSubStr{\docname}{credit_note}{ + \newcommand{\doctype}{\TitleCreditNote} + \newcommand{\MyDocdate}{\invdate} + \newcommand{\DocNoTitle}{\CredNumber} + \newcommand{\docnumber}{\invnumber} + % keine 2. Documentnummer + \newcommand{\SecNoTitle}{} + \newcommand{\secnumber}{} +}{} +\IfSubStr{\docname}{sales_order}{ + % Auftragsbestaetigung + \newcommand{\doctype}{\TitleSalesOrder} + \newcommand{\MyDocdate}{\orddate} + \renewcommand{\deliverydate}{\reqdate} + \newcommand{\DocNoTitle}{\OrderNumber} + \newcommand{\docnumber}{\ordnumber} + % 2. Documentnummer + \ifthenelse{\equal{\ordnumber}{\leer}}{ + % wenn keine Angebotsnummer -> leer + \newcommand{\SecNoTitle}{} + \newcommand{\secnumber}{} + }{ + \newcommand{\SecNoTitle}{\QuotationNumber} + \newcommand{\secnumber}{\quonumber} + } +}{ } +\IfSubStr{\docname}{sales_quotation}{ + % Angebot + \newcommand{\doctype}{\TitleSalesQuotation} + \newcommand{\MyDocdate}{\quodate} + \renewcommand{\DelDate}{\ValidUntil} + \renewcommand{\deliverydate}{\reqdate} + \newcommand{\DocNoTitle}{\QuotationNumber} + \newcommand{\docnumber}{\quonumber} + % 2. Documentnummer + \newcommand{\SecNoTitle}{} + \newcommand{\secnumber}{} +}{ } + + + +% ==== \paid auf 0.00 falls leer +\IfSubStr{\paid}{\DecimalSign}{}{\renewcommand{\paid}{0{\DecimalSign}00}} + + + +\setkomavar{date}{} + + +\begin{letter}{{\ifthenelse{\isnamedefined{MyAdressfield}}{\MyAdressfield + }{\MyAdress + }} +} +\opening{} + +%========Datum und Nummern==================================================== + +\newcommand{\DocId}{ + \begin{tabular*}{\textwidth+1em }{@{\extracolsep{\fill}}llllr} + \MakeUppercase{\tiny \DocNoTitle} & + \MakeUppercase{\tiny \CustomerID} & + \MakeUppercase{\tiny \SecNoTitle } & + \MakeUppercase{\tiny \DelDate } & + \MakeUppercase{\tiny \Date}~\\ + \mainfont\docnumber & + \mainfont\kundennummer & + \mainfont\secnumber & + \mainfont\deliverydate & + \mainfont\MyDocdate~\\ +\end{tabular*} ~\\ +} + +\hspace{-0.5em} \DocId + + + + +\nexthead{ + \ifthenelse{\bgPdfFirstPageOnly = 1 }{ + \hspace{-4mm} \DocId + }{} +} +\vspace{ 5mm} + +{\noindent\textbf\doctype}~\\ +\IfEndWith{\paymenttype}{\paymentPrivatEnd}{\PriceInclTax }{ } + + +%======Die eigentliche-Tabelle======================================== + +% temporaere Datei mit Tabelle anlegen +\begin{filecontents}{tabelle.tex} +\mainfont +\resetlaufsumme + + + + \ifthenelse{\NoValue > 0 } + { % Tabelle ohne Preisen + \ifthenelse{\Picklist = 1 }{ + + \begin{longtable}{@{}rlX@{ }rlrrrl@{}} + }{ + \begin{longtable}{@{}rlX@{ }rlrr@{}} + + } + % Kopfzeile der Tabelle + + {\Pos} & + {\Number} & + {\ItemNo} & + {\Count} & + {\Unit} \hspace{2mm} + \ifthenelse{\Picklist = 1 }{& {\Take} & {\Storage} }{} + ~\\ + \midrule + \endfirsthead + + % Tabellenkopf nach dem Umbruch + {\Pos} & + {\Number} & + {\ItemNo} & + {\Count} & + {\Unit} \hspace{2mm} + \ifthenelse{\Picklist = 1 }{& {\Take} & {\Storage} }{} + ~\\ + + \midrule + \endhead + + <%foreach number%> + <%runningnumber%> % Laufende Positionsnummer + & + <%number%> % Artikelnummer + & + <%description%> % Kurzbeschreibung des Artikels + \ifthenelse{\equal{<%longdescription%>}{\leer}}{}{ \newline <%longdescription%>} + % Ein zeilenweises Auslieferdatum, wenn es gesetzt bei der Position hinterlegt ist. + \ifthenelse{\equal{<%deliverydate_oe%>}{\leer}}{}{ + \newline \DelDate:~<%deliverydate_oe%>} + & + <%qty NOFORMAT%> % Menge + & + <%unit%> % Einheit + %\ifthenelse{\Picklist = 1 }{& {x} & {x} }{} + %\ifthenelse{\Picklist = 1 }{& {x} & {x} \hhline{~~~~~--} }{~\\} + \ifthenelse{\Picklist = 1 }{& {\underline{;~~~~~~~~~}} & {\underline{;~~~~~~~~~}}~\\ }{~\\} + %~\\ % + <%end number%> + \end{longtable} % Ende der zentralen Tabelle + }{ % Tabelle mit Preisen + \begin{longtable}{@{}rlX@{ }rlrrr@{}} + % Kopfzeile der Tabelle + + {\Pos} & + {\Number} & + {\ItemNo} & + {\Count} & + {\Unit} & + {\Fee} & + {\Dis} & + {\Total} \hspace{2mm} ~\\ + \midrule + \endfirsthead + + % Tabellenkopf nach dem Umbruch + {\Pos} & + {\Number} & + {\ItemNo} & + {\Count} & + {\Unit} & + {\Fee} & + {\Dis} & + {\Total} \hspace{2mm} ~\\ + \midrule + \multicolumn{7}{r}{ \rule{0mm}{5mm} \TabCarry{:} \MarkZwsumPos} + \endhead + + + % Fuss der Teiltabellen + \multicolumn{7}{r}{ \rule{0mm}{5mm} \TabSubTotal{:} \MarkZwsumPos } ~\\ + \endfoot + + % Das Ende der Tabelle + \midrule + \multicolumn{7}{r}{ \rule{0mm}{5mm} \TabSubTotal{:} \MarkZwsumPos} ~\\ + \endlastfoot + + <%foreach number%> + <%runningnumber%> % Laufende Positionsnummer + & + <%number%> % Artikelnummer + & + <%description%> % Kurzbeschreibung des Artikels + \ifthenelse{\equal{<%longdescription%>}{\leer}}{}{ \newline <%longdescription%>} + % Ein zeilenweises Auslieferdatum, wenn es gesetzt ist. + \ifthenelse{\equal{<%reqdate%>}{\leer}}{}{ + \newline \DelDate:~<%reqdate%>} + & + <%qty NOFORMAT%> % Menge + & + <%unit%> % Einheit + & + %\IfEndWith{\paymentterms}{_e}{EN}{\brutto{<%sellprice NOFORMAT%>}{<%qty NOFORMAT%>}{<%p_discount%>}} + \IfEndWith{\paymenttype}{\paymentPrivatEnd}{ + \BruttoSellPrice{<%sellprice NOFORMAT%>}{<%tax_rate%>} + & + \ifthenelse{\equal{<%p_discount%>}{0}}{}{ -<%p_discount%>\%} + & + \BruttoWert{<%linetotal NOFORMAT%>}{<%tax_rate%>} + }{ + \numprint{<%sellprice NOFORMAT%>} + & + \ifthenelse{\equal{<%p_discount%>}{0}}{}{ -<%p_discount%>\%} + & + \Wert{<%linetotal NOFORMAT%>} % Zeilensumme addieren + } + ~\\ % + <%end number%> + \end{longtable} % Ende der zentralen Tabelle + } +\end{filecontents} % Ende der Hilfsdatei. + +\LTXtable{\textwidth}{tabelle.tex} + +\rule{\textwidth}{0pt} % Ein (unsichtbarer) Strich quer ueber die Seite +\vspace{ 5mm} +\vspace{-2em plus 10em minus 2em}~\\ +\ifthenelse{\NoValue > 0 } +{ % wenn keine Zahlen +}{ % Wenn Zahlen + \parbox{\textwidth}{ + \mainfont + % + % + \setlength{\tabcolsep}{0.2em} + \ifthenelse{\equal{\paid}{0{\DecimalSign}00} } + { % Wenn noch nichts gezahlt wurde + \IfSubStr{\invtotal}{\DecimalSign}{}{ + \fpAdd{\invtotal}{0}{<%subtotal NOFORMAT%>} + <%foreach tax%> + \fpAdd{\invtotal}{\invtotal}{<%tax NOFORMAT%>} + <%end tax%> + } + \hfill + \begin{tabular}{@{}rrr@{}} + %{Summe vor Steuern:}& {\numprint{<%subtotal NOFORMAT%>}} & ~\\ + + % Die unterschiedlichen Steueranteile getrennt ausweisen + <%foreach tax%> + { \IfEndWith{\paymenttype}{\paymentPrivatEnd}{\TaxInc }{ } <%taxdescription%>} + & + {\numprint{<%tax NOFORMAT%>}}& ~\\ + <%end tax%> + \midrule[1pt] + {\Sum~ \currency:} & \textbf{\numprint{\invtotal}} + \end{tabular} + } + { % Wenn bereits etwas gezahlt wurde + \hfill + \begin{tabular}{@{}rrr@{}} + + {\EbT}& {\numprint{<%subtotal NOFORMAT%>}} & ~\\ + + % Die unterschiedlichen Steueranteile getrennt ausweisen + <%foreach tax%> + {<%taxdescription%>} + & + {\numprint{<%tax NOFORMAT%>}}& ~\\ + <%end tax%> + + \midrule % Ein dünner Strich + \Sum & \numprint{\invtotal} & ~\\ + + <%foreach payment%> + \AlreadyPayed~ {<%paymentdate%>}:& -{\numprint{<%payment%>}} & ~\\ + <%end paymentdate%> + + \midrule[2pt] % Ein etwas dickerer Strich + {\Left~ \currency:} & \numprint{\total} + \end{tabular} + }% ende ithenelse + + } %Ende des Summenkasten +} + +\vfill % Den Rest-Text soweit wie möglich nach unten schieben +\ifthenelse{\isempty{<%notes%>}}{}{ + \mainfont +\noindent <%notes%> ~\\[2em] + }% +\small +\noindent \YourOrder +\ifthenelse{\Picklist = 0}{\noindent \ifthenelse{\equal{<%ustid%>}{\leer}}{}{\UstidTitle} \UstId}{} +\noindent \paymenthints % ist in translations.tex deffiniert +\ifthenelse{\PurchaseOrder = 0}{\noindent \paymentterms}{} + + +\end{letter} +\end{document} diff --git a/templates/f-tex/mydata.tex.example b/templates/f-tex/mydata.tex.example new file mode 100644 index 000000000..6758fec9c --- /dev/null +++ b/templates/f-tex/mydata.tex.example @@ -0,0 +1,21 @@ + +% \employeecountry wird fuer lxo fancy LaTeX benoetigt +\newcommand{\employeecountry}{Deutschland} + + + +% die folgenden definitionen koennten auch direkt in der Steuerdatei *.lco stehen +\newcommand{\MYfromname}{Die globalen Problemlöser} +\newcommand{\MYaddrsecrow}{Gesellschaft für anderer Leute Sorgen mbH} +\newcommand{\MYrechtsform}{Handelsregister: HRA 123456789 } +\newcommand{\MYfromaddress}{Hauptstraße 5\\12345 Hier} +\newcommand{\MYfromphone}{Tel: +49 (0)12 3456780} +\newcommand{\MYfromfax}{Fax: +49 (0)12 3456781} +\newcommand{\MYfromemail}{mail@g-problemloeser.com} +\newcommand{\MYsignature}{Herbert Wichtig - Geschäftsführer} +\newcommand{\MYustid}{UstID: DE 123 456 789} +\newcommand{\MYfrombank}{Bankverbindung\\ + Ensifera Bank\\ + Kto 1234567800\\ + BLZ 123 456 78 +} diff --git a/templates/f-tex/sample.lco b/templates/f-tex/sample.lco new file mode 100644 index 000000000..a76a4b458 --- /dev/null +++ b/templates/f-tex/sample.lco @@ -0,0 +1,142 @@ +% ---------------------------------------------------------- +% letter.lco +% Steuerdatei Briefklasse f-tex +% +% Changelog: see gitlog + \newcommand{\ftLcoVTversion}{1.0-u (16.11.2011)} +% +% Lizenz +% http://www.gnu.de/licenses/gpl-3.0.html +% +% Siehe ./README +% +% Autor: Wulf Coulmann scripts_at_gpl.coulmann.de +% +% +% ---------------------------------------------------------- + + +\begingroup + \makeatletter + \@latex@warning@no@line{ #### this is letter.lco \ftLcoVTversion #####} +\endgroup + + + +\ProvidesFile{letter.lco}[% + 2002/07/09 v0.9a LaTeX2e unsupported letter-class-option] + +\KOMAoptions{foldmarks=false} +\usepackage{graphicx} +\usepackage[utf8]{inputenc} +\usepackage{ngerman} +\usepackage{lmodern} +\usepackage{xcolor} +\usepackage{watermark} +\usepackage{xifthen} + + +% ================== settings ============================== + + % Name der pdf Datei die den Briefkopf enthaelt + \newcommand{\bgPdfName}{letter_head.pdf} + + % Hintergrund pdf nur bei erster Dokumentseite [1|0] + \newcommand{\bgPdfFirstPageOnly}{1} + + % Hintergrundpdf nur bei versand per email [1|0] + % (setze diesen Wert auf 1, wenn auf bereits Bedruktes Briefpapier ausgedruckt werden soll) + \newcommand{\bgPdfEmailOnly}{0} + + % Trennlienie unter der Seitenkopfzeile ab Seite 2 ff. + \KOMAoptions{headsepline=on} + + % der Abstand zu den Fusszeilen + \addtolength{\textheight}{23mm} + + % zusaetzlicher Zwischenraum zur Fusszeile ab Seite 2 ff. + % (nur bei bgPdfFirstPageOnly = 1) + \addtolength{\footskip}{10mm} + + +% ================== end settings ============================== + + + +\setkomavar{backaddress}{} + +\setkomavar{fromname}{\MYfromname} +\newcommand\addrsecrow{\MYaddrsecrow} +\newcommand\rechtsform{\MYrechtsform} +\setkomavar{fromaddress}{\MYfromaddress} +\setkomavar{fromphone}{\MYfromphone} +\setkomavar{fromfax}{\MYfromfax} +\setkomavar{fromemail}{\MYfromemail} +\setkomavar{signature}{\MYsignature} +\newcommand\ustid{\MYustid} +\setkomavar{frombank}{\MYfrombank} + +\renewcommand{\rmdefault}{cmss} +\newlength\entrytblsub +\setlength\entrytblsub{\dimexpr\tabcolsep+1.3mm+\arrayrulewidth\relax} +\setlength\textwidth{166mm} +\oddsidemargin -0.4mm +\KOMAoptions{headsepline=on} + +\pagestyle{myheadings} +\@addtoplength{firstfootvpos}{18mm} +\@addtoplength{foldmarkhpos}{5mm} +\@setplength{firstheadvpos}{0mm} +\@setplength{firstheadwidth}{165mm} +\@setplength{firstfootwidth}{165mm} +\@setplength{toaddrhpos}{25mm} +\@setplength{toaddrvpos}{38mm} +\@setplength{refhpos}{26mm} +\@addtoplength{refvpos}{-18mm} + +\font\mainfont=cmss9 + + + +\ifthenelse{\bgPdfFirstPageOnly = 0 }{ + \addtolength{\headheight}{50mm} + \watermark{ + \setlength{\unitlength}{1mm} + \put(-22,-226){ + \includegraphics[width=210mm]{\bgPdfName} + } + } +}{} + +\firsthead{ + \ifthenelse{\bgPdfFirstPageOnly = 1 }{ + \put(-69,0){ % Mit diesem put-Befehl wird die Position des Logos bestimmt. + \includegraphics[width=210mm]{\bgPdfName} + } + }{} +} + + + + +\firstfoot{% +} + +\nextfoot{% + \parbox{\useplength{firstfootwidth}}{ + \hspace{-\entrytblsub} + \begin{tabular}{l} + \usekomavar{fromname} + \end{tabular}\hfill + \begin{tabular}{r} + \thepage + \end{tabular} + \hspace{-\entrytblsub} + } + \vspace{10mm} +} + + + +\endinput +% vim: set filetype=tex :EOF diff --git a/templates/f-tex/sample_head.pdf b/templates/f-tex/sample_head.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6d14e7eea23cb8ecfd3aa335c8b66d6c43e3db57 GIT binary patch literal 73601 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≫}=i!NUr{^;+`k;&x}!)$i6hf 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 L*x8k|l>z?)NJ}Z! literal 0 HcmV?d00001 diff --git a/templates/f-tex/setup.sh b/templates/f-tex/setup.sh new file mode 100755 index 000000000..b557e8061 --- /dev/null +++ b/templates/f-tex/setup.sh @@ -0,0 +1,1082 @@ +#!/bin/bash + + +# Setup script fuer die Nutzung der fancy-LaTeX Umgebung oder +# der Label-Print erweiterung (lp) in LX-Office-erp. +# Welches Setup ist von der Position innerhalb des Dateisystems abhaengig. +# Das Script kann auch nach erfolgtem Setup erneut aufgerufen werden + +# see ./setup.sh -h + + + + + +# Revision 0.2 (13.02.2011) add lp +# setup add determination of company data +# Revision 0.1 (19.12.2010) initial script create + + +# config + +DB_AUTH='../../config/lx_office.conf' + +FILE_LIST_FTEX=' + letter.tex + sample.lco + sample_head.pdf + translations.tex + xstring.sty + zwischensumme.sty +' + +FILE_LIST_LP=' + label_abs_a7_de.tex + label_nn_brief_a4_de.tex + zweckform_3427.tdf + zweckform_3483.tdf +' + + +DOC_TYPE_FTEX=' + invoice + proforma + sales_quotation + sales_order + sales_delivery_order + credit_note + pick_list + purchase_order +' + + +LXO_DETERMINE=' + ../../SL/Form.pm + ../../config/lx_office.conf.default + ../../doc/changelog +' + +CHK_RAWNUMBER_PATCH=' + ../../SL/DO.pm + ../../SL/IS.pm + ../../SL/OE.pm +' + +MY_DATA=' + employeecountry + labelcompanyname + labelbankname + labelbankcode + labelbankaccount + MYfromname + MYaddrsecrow + MYrechtsform + MYfromaddress + MYfromphone + MYfromfax + MYfromemail + MYsignature + MYustid + MYfrombank +' + +BASE_DIR=`readlink -f $0 | sed 's/setup\.sh$//'` + +MODUL=`basename ${BASE_DIR}` +export TEXINPUTS=".:${BASE_DIR}:" + +OK='...... [ok]' +MARK='\033[1;34m' +UNMARK='\033[0m' +TIME=`date +%s` + +USAGE="\n\n setup LaTeX templates for lx-office erp (www.lx-office.org) +\n\n USAGE: ./`basename $0` [OPTION] \n +\n + -h print this Help\n +\n +\n + OPTIONS for trouble shooting:\n\n + -D don't connect to any database\n + -C no colored output (don't use any terminal escape character)\n +\n\n + RECOMMENDED USE ./setup.sh + +\n +" + +# script control + +DATABASE=1 + +while getopts "hDC" flag +do + case $flag in + h) + echo -e ${USAGE} + exit + ;; + D) + DATABASE=0 + ;; + C) + NO_COLOR=1 + ;; + esac +done + +# Disclaim + +cat << EOD + + ########################################################################## + # Disclaimer # + ########################################################################## + # # + # Dies ist ein Script zum Einrichten von LaTeX Templates # + # (fancy-latex (f-tex)) oder (label-print (lp) fuer # + # # + # lx-office erp (www.lx-erp.org) # + # # + # Obwohl LX-Office sich an deutschsprachige Anwender richtet ist dieses # + # Script in Englisch und soll auch nicht uebersetzt werden. # + # # + # * es richtet sich an System-Administratoren # + # * da es das Script nur in einer Sprache gibt, ist es viel leichter # + # bei Fehlern und Fehlermeldungen aus dem Script selbst, im Internet # + # nach Loesungen zu suchen. # + # # + ########################################################################## + # # + # This script provides an easy to use setup for the fancy LaTeX # + # environment of lx-office erp (templates/f-tex) # + # # + # Normal use is to run ./setup.sh without any parameter. You may also # + # check # + # ./setup.sh -h # + # for help. # + # # + # The script tries to be as save as possible to avoid unwanted file # + # overwriting by being very interactive. It's designed to be invoked # + # multiple times inside the same template directory. So it is possible # + # to rerun the script if there are updates available or after you break # + # your LaTeX templates by any changes. # + # # + # I recommend to backup your installation and database before you run # + # this script. # + # # + # ANYHOW: I do not take responsibility for any harm initiated by this # + # script. (Wulf Coulmann -- scripts_at_gpl.coulmann.de) # + # # + ########################################################################## + + +EOD + +QUESTION=' I understand the above warnings [YES/NO/Q]:' + +echo -n "${QUESTION} " + + +[ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} +read ANSWER +[ "${NO_COLOR}" = 1 ] || echo -ne "${UNMARK}" + + +until [ "${ANSWER}" = YES ]\ + || [ "${ANSWER}" = NO ] \ + || [ "${ANSWER}" = N ] \ + || [ "${ANSWER}" = n ] \ + || [ "${ANSWER}" = q ] \ + || [ "${ANSWER}" = Q ] ; do + echo -n "${QUESTION} " + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + read ANSWER + [ "${NO_COLOR}" = 1 ] || echo -ne "${UNMARK}" +done + +case ${ANSWER} in + YES) + echo -n ' accepted' + ;; + NO|n|N|q|Q) + echo + echo ' script aborted by user input' + exit 72 + ;; +esac + + +FEEDBACK='################################\n # FEEDBACK:\n +' + + +# load functions + +function error { + echo '[error]' ...... $1 ...... '[terminate script]' + exit 72 +} + +function mark { + [ "${NO_COLOR}" = 1 ] || echo -ne "${MARK}" + echo -n "${1}" + [ "${NO_COLOR}" = 1 ] || echo -ne "${UNMARK}" +} + + + +function ask_yn { + local QUESTION=$1 + until [ "${ANSWER}" = y ]\ + || [ "${ANSWER}" = Y ] \ + || [ "${ANSWER}" = j ] \ + || [ "${ANSWER}" = J ] \ + || [ "${ANSWER}" = n ] \ + || [ "${ANSWER}" = N ] \ + || [ "${ANSWER}" = Q ] \ + || [ "${ANSWER}" = q ] ; do + echo -n "${QUESTION}" + read ANSWER + done + + case ${ANSWER} in + y|Y|j|J) + return + ;; + n|N) + return + ;; + q|Q) + [ "${NO_COLOR}" = 1 ] || echo -ne "${UNMARK}" + echo + echo ' script aborted by user input' + exit 72 + ;; + esac +} + +function latex_pack_check { + echo ' -> search LaTeX package '$1' ' + echo -n ' ' + if [ ! `kpsewhich ${1}.sty` ] ; then + echo + echo " can't find package ${1}" + echo " on debian systems you may install apt-file" + echo " aptitude install apt-file" + echo " apt-file update" + echo " apt-file search ${1}.sty" + echo " this will show which package contains the needet LaTeX .sty file" + echo " on other systems, please refer to their documentation on how to " + echo " find matching packages." + echo + echo " If you are done, rerun this script" + echo " [unsatisfied dependencies]' ...... ${1} ...... [terminate script]" + exit 72 + else + echo \ \ ${OK} + fi + +} + +function check_accepted_names { + echo ' -> check for suspect characters in '${2} + echo -n ${1} | egrep '[^-_\.!A-Za-z0-9]' && echo ' [suspect characters found] in ... '${2}' ... [terminate script]' && exit 72 +} + +function check_int { + echo ' -> check for suspect characters in '${2} + echo -n ${1} | egrep '[^0-9]' && echo ' [suspect characters found] in ... '${2}' ... [terminate script]' && exit 72 +} + +function create_file { + ANSWER=0 + if [ "${1}" = ln ] ;then + DO=1 + echo -n ' -> try to create symbolic link '${3} + if [ -e "${3}" ] ; then + if [ -L "${3}" ] ; then + if [ "`ls -l ${3} | awk '{print $10}'`" = "${2}" ]; then + echo ' ... symbolic link already exists, nothing to do!' + DO=0 + else + echo ' ... symbolic link with different target exist!' + ls -lah "${3}" + echo ' you may' + echo ' [d] delete and replace the current link' + echo ' [m] move current link to '${3}.${TIME}.old + echo ' [s] skip -- leave it as it is' + echo ' [q] abort setup.sh' + QUESTION=' what do do? [d/m/s/q]: ' + echo -en ${QUESTION} + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + read ANSWER + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + until [ "${ANSWER}" = D ] \ + || [ "${ANSWER}" = d ] \ + || [ "${ANSWER}" = m ] \ + || [ "${ANSWER}" = s ] \ + || [ "${ANSWER}" = q ] ; do + echo -n "${QUESTION}" + read ANSWER + done + + case ${ANSWER} in + d) + rm -f ${3} || error ' unable to delete symbolic link '${3} + ;; + m) + mv -f ${3} ${3}.${TIME}.old || error ' unable to move symbolic link '${3} + ;; + s) + echo ' as you decide, we leave it as it is!' + DO=0 + ;; + q) + [ "${NO_COLOR}" = 1 ] || echo -ne "${UNMARK}" + echo + echo ' script aborted by user input' + exit 72 + ;; + esac + fi + else + echo ' ... file already exists where I tried to create a symbolic link!' + ls -lah "${3}" + echo ' you may' + echo ' [S] show the file (exit file display with "q")' + echo ' [m] move current file to '${3}.${TIME}.old + echo ' [d] delete and replace the file with symbolic link' + echo ' [s] skip -- leave it as it is' + echo ' [q] abort setup.sh' + QUESTION='what to do? [S/d/m/s/q]:' + echo -en " ${QUESTION} " + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + read ANSWER + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + until [ "${ANSWER}" = S ] \ + || [ "${ANSWER}" = d ] \ + || [ "${ANSWER}" = m ] \ + || [ "${ANSWER}" = s ] \ + || [ "${ANSWER}" = q ] ; do + echo -n " ${QUESTION} " + read ANSWER + done + + case ${ANSWER} in + S) + echo + echo + less "${3}" + echo + echo + create_file "${1}" "${2}" "${3}" + return + ;; + m) + mv -f ${3} ${3}.${TIME}.old || error ' unable to move file '${3} + ;; + d) + rm -f ${3} || error ' unable to delete file '${3} + ;; + s) + echo ' as you decide, we leave it as it is!' + DO=0 + ;; + q) + [ "${NO_COLOR}" = 1 ] || echo -ne "${UNMARK}" + echo + echo ' script aborted by user input' + exit 72 + ;; + esac + fi + fi + if [ "${DO}" = "1" ] ;then ln -s "${2}" "${3}" || error ' failed to create symbolic link '${3} ; fi + [ "${DO}" = "1" ] && echo \ \ ${OK} + fi + + if [ "${1}" = cp ] ;then + echo -n ' -> try to copy file '${3} + DO=1 + if [ -e "${3}" ] ; then + echo ' ... file already exists!' + diff "${2}" "${3}" >/dev/null + if [ "$?" = 0 ] ; then + echo ' files are equal, we leave it as it is!' + DO=0 + else + ls -lah "${3}" + echo ' you may' + echo ' [D] show a diff between the new and current file' + echo ' [m] move current file to '${3}.${TIME}.old + echo ' [d] delete and replace with new file' + echo ' [s] skip -- leave it as it is' + echo ' [q] abort setup.sh' + QUESTION='what to do? [D/m/d/s/q]:' + echo -en " ${QUESTION} " + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + read ANSWER + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + until [ "${ANSWER}" = D ] \ + || [ "${ANSWER}" = d ] \ + || [ "${ANSWER}" = m ] \ + || [ "${ANSWER}" = s ] \ + || [ "${ANSWER}" = q ] ; do + echo -n " ${QUESTION} " + read ANSWER + done + + case ${ANSWER} in + D) + echo + echo + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + echo '---------------------------------------' + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + diff -C 3 "${2}" "${3}" + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + echo '---------------------------------------' + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo + echo + create_file "${1}" "${2}" "${3}" + ;; + m) + mv -f ${3} ${3}.${TIME}.old || error ' unable to move file '${3} + ;; + d) + rm -f ${3} || error ' unable to delete file '${3} + ;; + s) + echo ' as you decide, we leave it as it is!' + DO=0 + ;; + q) + [ "${NO_COLOR}" = 1 ] || echo -ne "${UNMARK}" + echo + echo ' script aborted by user input' + exit 72 + ;; + esac + fi + fi + if [ "${DO}" = "1" ] ;then cp "${2}" "${3}" || error ' failed to copy '${3} ; fi + [ "${DO}" = "1" ] && echo \ \ ${OK} + fi + +} + +function create_mydata { + + VALUE=${1} + DB=${2} + NODATA=' did not get a value corresponding to your template dir' + + SQL=" + SELECT regexp_replace( u1.cfg_value, E'\n' ,E'\\\\\\\\\\\\' || E'\n') + FROM auth.user_config u1, auth.user_config u2 + WHERE u1.user_id = u2.user_id + AND u1.cfg_key = '"${DB}"' + AND u2.cfg_key = 'templates' + AND u2.cfg_value = 'templates/"${TEMP_DIR}"' + ORDER BY u1.cfg_value DESC + LIMIT 1; + " + case ${DB} in + tel) + PRE='Tel:' + ;; + fax) + PRE='fax:' + ;; + co_ustid) + if [ ! `psql --pset tuples_only -h "${PGHOST}" -U "${PGUSER}" "${PGDATABASE}" -c "${SQL}"`"" ] ; then + SQL=" + SELECT regexp_replace( u1.cfg_value, E'\n' ,E'\\\\\\\\\\\\' || E'\n') + FROM auth.user_config u1, auth.user_config u2 + WHERE u1.user_id = u2.user_id + AND u1.cfg_key = 'taxnumber' + AND u2.cfg_key = 'templates' + AND u2.cfg_value = 'templates/"${TEMP_DIR}"' + ORDER BY u1.cfg_value DESC + LIMIT 1; + " + PRE='StNr.:' + else + PRE='UstIdNr:' + fi + ;; + *) + PRE='' + ;; + esac + + + + if [ "${2}" ] ; then + ANSWER=`psql --pset tuples_only -h "${PGHOST}" -U "${PGUSER}" "${PGDATABASE}" -c "${SQL}"` || error "unable to connect to auth db" + if [ ! "${VALUE}" ] ; then + echo ' please fix this later' + ANSWER=FIX_ME + else + echo ' found: '${ANSWER} + fi + else + if [ ! "${2}" ] && [ ${1} = "employeecountry" ] ; then + read ANSWER + else + echo ' please fix this later' + ANSWER=FIX_ME + fi + fi + + echo -e "\0134"'newcommand{'"\0134"${VALUE}'}{'${PRE}${ANSWER}'}' >> mydata.tex + +} + +function read_db_conf { + + perl -e 'use Config::Std; + read_config "'${DB_AUTH}'.default" => my %config_default; + my $val_default = $config_default{"authentication/database"}{'${1}'}; + read_config "'${DB_AUTH}'" => %config; + my $val = $config{"authentication/database"}{'${1}'} if $config{"authentication/database"}{'${1}'}; + if ( $val ) { + print $val; + }else{ + print $val_default; + }' + +} + + + + + +# check for dependencies +echo -n ' -> search kpsewhich ' + which kpsewhich >/dev/null + [ "$?" = 0 ] || error 'unable find programm "kpsewhich" -- is there a propper installed LaTeX? (on debian: aptitude install texlive-base-bin)' + echo \ \ ${OK} + +if [ "${MODUL}" = "f-tex" ] ; then + echo ' -> search LaTeX documentclass scrlttr2' + echo -n ' ' + if [ ! `kpsewhich scrlttr2.cls` ] ; then + echo + echo " can't find documentclass scrlttr2" + echo " on debian systems you may install it by" + echo " aptitude install texlive-latex-recommended" + echo " on other systems, please refer to their documentation how to find" + echo " matching packages." + echo + echo " If you are done, rerun this script" + echo " [unsatisfied dependencies]' ...... documentclass scrlttr2 ...... [terminate script]" + exit 72 + else + echo \ \ ${OK} + fi +elif [ "${MODUL}" = "lp" ] ; then + echo ' -> search LaTeX package ticket and check vor needed version ' + echo -n ' ' + HOLD_TEXINPUTS=${TEXINPUTS} + export TEXINPUTS='' + if [ `kpsewhich ticket.sty` ] ; then + grep rowmode `kpsewhich ticket.sty` > /dev/null + if [ "$?" -gt "0" ] ;then + FILE_LIST_LP=${FILE_LIST_LP}" ticket.sty" + echo \ \ "your version of LaTeX Package ticket does not support rowmode - we use our own ticket.sty" + echo \ \ \ \ \ \ "ticket.sty supports option rowmode from version v0.4b" + echo \ \ \ \ \ \ ${OK} + fi + else + FILE_LIST_LP=${FILE_LIST_LP}" ticket.sty" + echo \ \ "can't find LaTeX Package ticket, but we use our own ticket.sty because we need version => v0.4b" + echo \ \ \ \ \ \ "ticket.sty supports option rowmode from version v0.4b" + echo \ \ \ \ \ \ ${OK} + fi + export TEXINPUTS=${HOLD_TEXINPUTS} +else + error "no valid install modul - is the install script inside ~/templates/f-tex or ~/templates/lp ?" +fi + +for PACK in `grep usepackage ${BASE_DIR}/*.tex ${BASE_DIR}/*.sty ${BASE_DIR}/*.lco |awk -F '{' '{print $2}'|awk -F '}' '{print $1}'| sort | uniq`; do + latex_pack_check ${PACK} +done + + +# decide the installation target (template directory) +echo -n ' -> cd to base directory: '${BASE_DIR}' ' + + cd ${BASE_DIR} || error "unable to change directory" + echo \ \ ${OK} + + + +echo ' -> check if we are inside an lxo installation' + +if [ ! -e ../../SL/Form.pm ] ; then + + dpkg -l | grep lx-office-erp | egrep '^ii' + if [ "$?" = 0 ] ; then + echo ' seams like this is a Debian-package' + DB_AUTH='/etc/lx-office-erp/lx_office.conf' + + LXO_DETERMINE=' + /usr/lib/lx-office-erp/SL/Form.pm + /etc/lx-office-erp/lx_office.conf.default + /usr/share/doc/lx-office-erp/changelog + ' + + CHK_RAWNUMBER_PATCH=' + /usr/lib/lx-office-erp/SL/DO.pm + /usr/lib/lx-office-erp/SL/IS.pm + /usr/lib/lx-office-erp/SL/OE.pm + ' + + fi + +fi + +for now in ${LXO_DETERMINE} ; do + [ -e ${now} ] || error 'missing '${now}', do not run this script outside an lx-office installation!. Is setup.sh located inside an lxo installation in templates/'${MODUL}'?' +done +echo \ \ ${OK} + +if [ "${MODUL}" = "f-tex" ] ; then + echo ' -> search raw numbers patch ' + RAW_NUM=`egrep -oh '\{[^{]*_nofmt\}' ${CHK_RAWNUMBER_PATCH} |wc -l` + + if [ "${RAW_NUM}" -lt 20 ] ; then + echo ' did not find the raw_number values' + echo + egrep -oh '\{[^{]*_nofmt\}' ${CHK_RAWNUMBER_PATCH} + echo ' seems like you added fancy LaTeX separate and needed raw_number values are missing' + echo ' this is already part of the dev-source code.' + echo ' please use this script in the environment you got it from' + error 'missing raw_number values' + fi + echo \ \ ${OK} +fi + + +if [ ${DATABASE} = 1 ] ; then + + echo ' -> request Auth-DB ' + [ -r ${DB_AUTH} ] || [ -r ${DB_AUTH}.default ] || error "unable to read ${DB_AUTH} or ${DB_AUTH}.default -- you must be able to read db credentials" + + export PGDATABASE=`read_db_conf db` + check_accepted_names ${PGDATABASE} database_name + export PGPASSWORD=`read_db_conf password` + check_accepted_names ${PGPASSWORD} database_pw + export PGUSER=`read_db_conf user` + check_accepted_names ${PGUSER} database_user + export PGPORT=`read_db_conf port` + [ "${#PGPORT}" -lt 1 ] && PGPORT=5432 + check_int ${PGPORT} database_port + export PGHOST=`read_db_conf host` + [ "${#PGHOST}" -lt 1 ] && PGHOST=localhost + check_accepted_names ${PGHOST} database_host + + SQL=" + SELECT + substring(cfg_value from E'[^/]*$') as template_dir + FROM auth.user_config + WHERE cfg_key = 'templates' + GROUP BY cfg_value ; + " + + + echo ' -> search active template dirs ' + echo + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + + psql --pset tuples_only -h "${PGHOST}" -U "${PGUSER}" "${PGDATABASE}" -c "${SQL}" || error "unable to connect to auth db" + + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo ' I found the above listed template directorys in '`mark '[lxo-home]/templates'`' by requesting your user configuration.' + echo ' in database '`mark "${PGDATABASE}"`'.' +fi + +echo ' Type in which template directory to use (by typing in a name)' +echo ' * if template_dir does not exist, it will be created' +echo ' * template_dir must also be configured in your user administration' +echo ' to make it active.' +echo +echo -en ' type name of template dirctory: ' +[ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} +read TEMP_DIR +[ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + + +[ "${#TEMP_DIR}" -gt 0 ] || error 'no value for template dir provided ' + + +if [ -d "../${TEMP_DIR}" ] ; then + MV_DIR=${TEMP_DIR}.${TIME}.old + echo + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + ls -lah ../${TEMP_DIR} + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo + echo ' the directory already exists and contains the above listed files' + echo ' you can:' + echo -e ' - move the directory to '`mark "templates/${MV_DIR}"`' and create a empty one, or' + echo ' - install the templates in the existing directory by interactive overwriting existing files' + echo + ask_yn ' move templates/'${TEMP_DIR}' to templates/'${MV_DIR}'? [y/n/q]: ' + + + + if [ "${ANSWER}" = y ] ; then + echo ' -> check for permission to move template directory ' + mv -i ../${TEMP_DIR} ../${MV_DIR} || error "unable to move directory " + echo -n ' -> original directory moved to '${MV_DIR} + echo \ \ ${OK} + fi + if [ "${ANSWER}" = n ] ; then + echo ' -> check for permission to write in template directory [lxo-home]/templates/'${TEMP_DIR} + [ -w ../${TEMP_DIR} ] || error "no permission to write directory " + echo \ \ ${OK} + fi + ANSWER=0 +fi + + +if [ ! -d "../${TEMP_DIR}" ] ; then + echo -n ' -> check for permission to create new template directory ' + mkdir "../"${TEMP_DIR} || error "unable to write to `echo ${PWD} | sed 's/\/'${MODUL}'$//'` -- you must be able to write in ~/templates " + echo \ \ ${OK} + echo -n ' -> '${TEMP_DIR}' created' + echo \ \ ${OK} +fi + +echo -n ' -> cd to template directory: '${TEMP_DIR}' ' + + cd ../${TEMP_DIR} || error "unable to change directory" + echo \ \ ${OK} +pwd + + +if [ -e mydata.tex ] ;then + echo ' -> check mydata.tex' + grep koma ./mydata.tex && FEEDBACK=${FEEDBACK}' # looks like a DEPRECATED mydata.tex -- please compare to f-tex/mydata.tex.example \n' + for now in ${MY_DATA} ; do + grep ${now} ./mydata.tex || FEEDBACK=${FEEDBACK}' # missing '${now}' in mydata.tex -- please compare to f-tex/mydata.tex.example \n' + done + + echo -e \ \ "your current mydata.tex looks like" + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + cat mydata.tex + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + +else + if [ ${DATABASE} = 1 ] ; then + # mydata voodooo goes here + SQL=" + SELECT + u1.cfg_value as company, + u2.cfg_value as address, + u3.cfg_value as tel, + u4.cfg_value as fax, + u5.cfg_value as texnumber, + u6.cfg_value as co_ustid + FROM + auth.user_config u1, + auth.user_config u2, + auth.user_config u3, + auth.user_config u4, + auth.user_config u5, + auth.user_config u6 + WHERE + u1.user_id = u2.user_id and + u2.user_id = u3.user_id and + u3.user_id = u4.user_id and + u4.user_id = u5.user_id and + u5.user_id = u6.user_id and + u1.cfg_key = 'company' and + u2.cfg_key = 'address' and + u3.cfg_key = 'tel' and + u4.cfg_key = 'fax' and + u5.cfg_key = 'taxnumber' and + u6.cfg_key = 'co_ustid' + GROUP BY + u1.cfg_value, + u2.cfg_value, + u3.cfg_value, + u4.cfg_value, + u5.cfg_value, + u6.cfg_value + ORDER BY + company; + " +# [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} +# +# psql -h "${PGHOST}" -U "${PGUSER}" "${PGDATABASE}" -c "${SQL}" || error "unable to connect to auth db" +# +# [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo ' There is no mydata.tex, we try to create it' + echo ' please answer the following questions' + echo -n ' - country your company is located eg:"Deutschland" : ' + create_mydata employeecountry + echo ' - owner of the bankaccount for label print' + echo ' used for "pay on delivery (Nachnahme)"' + echo -n ' type ~ instead of blanks eg: "Herbert~Wichtig" : ' + create_mydata labelcompanyname + echo ' - name of the bank for label print' + echo ' used for "pay on delivery (Nachnahme)"' + echo -n ' type ~ instad of blanks eg: "Ensifera~Bank" : ' + create_mydata labelbankname + echo ' - bank account number for label print' + echo ' used for "pay on delivery (Nachnahme)"' + echo -n ' no blanks eg: "123456789" : ' + create_mydata labelbankcode + echo ' - bank code (BLZ) for label print' + echo ' used for "pay on delivery (Nachnahme)' + echo -n ' no blanks eg: "10010010" : ' + create_mydata labelbankaccount + echo ' - company name for dokuments' + echo ' used for invoice, sales_quotation, etc.' + echo -n ' eg: "Die globalen Problemlöser" : ' + create_mydata MYfromname company + echo ' - company name second row for documents' + echo ' used for invoice, sales_quotation, etc.' + echo -n ' eg: "Gesellschaft für anderer Leute Sorgen mbH" : ' + create_mydata MYaddrsecrow + echo ' - legal form for documents' + echo ' used for invoice, sales_quotation, etc.' + echo ' eg: "Handelsregister: HRA 123456789" : ' + echo -n ' or: "Inhaber Herbert Wichtig" : ' + create_mydata MYrechtsform + echo ' - company address for documents' + echo ' used for invoice, sales_quotation, etc.' + echo ' multirow, type \\ as row dilimiter ' + echo -n ' eg: "Hauptstraße 5\\12345 Hier" : ' + create_mydata MYfromaddress address + echo ' - tel for documents' + echo ' used for invoice, sales_quotation, etc.' + echo -n ' eg: "Tel: +49 (0)12 3456780" : ' + create_mydata MYfromphone tel + echo ' - fax for documents' + echo ' used for invoice, sales_quotation, etc.' + echo -n ' eg: "Fax: +49 (0)12 3456781" : ' + create_mydata MYfromfax fax + echo ' - email for documents' + echo ' used for invoice, sales_quotation, etc.' + echo -n ' eg: "mail@g-problemloeser.com" : ' + create_mydata MYfromemail + echo ' - signatur for documents' + echo ' used for invoice, sales_quotation, etc.' + echo -n ' eg: "Herbert Wichtig - Geschäftsführer" : ' + create_mydata MYsignature + echo ' - tax number for documents' + echo ' used for invoice, sales_quotation, etc.' + echo ' it is common to use ustid but if you have none' + echo ' type in your main tax number' + echo ' eg: "UstID: DE 123 456 789" : ' + echo -n ' or: "StrNr: 12/345/6789" : ' + create_mydata MYustid co_ustid + echo ' - bank account for documents' + echo ' used for invoice, sales_quotation, etc.' + echo ' multirow, type \\ as row delimiter ' + echo -n ' eg: "Bankverbindung\\Ensifera Bank\\Kto 1234567800\\BLZ 123 456 78" : ' + create_mydata MYfrombank + + # damn escaping -- gnarf + perl -pi -e 's/([^\$\{])\\/$1\\\\/g' mydata.tex + perl -pi -e 's/([\&\%])/\\$1/g' mydata.tex + else + cp ../f-tex/mydata.tex.example mydata.tex + FEEDBACK=${FEEDBACK}' # I generate a mydata.tex please edit this file to match to your needs \n' + fi + FEEDBACK=${FEEDBACK}' # I generate a mydata.tex please edit this file to match to your needs \n' +fi + + +if [ "${MODUL}" = "f-tex" ] ; then + # search for installed languages + if [ ${DATABASE} = 1 ] ; then + SQL=" + SELECT + u1.cfg_value || ';' || + u2.cfg_value || ';' || + u3.cfg_value || ';' || + u4.cfg_value || ';' || + u5.cfg_value + FROM + auth.user_config u1, + auth.user_config u2, + auth.user_config u3, + auth.user_config u4, + auth.user_config u5 + WHERE + u1.user_id = u2.user_id and + u2.user_id = u3.user_id and + u3.user_id = u4.user_id and + u4.user_id = u5.user_id and + u1.cfg_key = 'dbname' and + u2.cfg_key = 'dbhost' and + u3.cfg_key = 'dbport' and + u4.cfg_key = 'dbuser' and + u5.cfg_key = 'dbpasswd' + GROUP BY + u1.cfg_value, + u2.cfg_value, + u3.cfg_value, + u4.cfg_value, + u5.cfg_value; + " + + echo ' -> try to determine aktive languages ....' + echo ' -> search database '${PGDATABASE}' to find lxo-erp databases ....' + + DBS=`psql --pset tuples_only -h "${PGHOST}" -U "${PGUSER}" "${PGDATABASE}" -c "${SQL}"` || error "unable to connect to auth db" + + for db in ${DBS} ; do + + PGDATABASE=`echo -n ${db} | awk -F ';' '{print $1}'` + echo -e ' -> prepare to request db '`mark ${PGDATABASE}` + check_accepted_names ${PGDATABASE} database_name + PGHOST=`echo -n ${db} | awk -F ';' '{print $2}'` + [ "${#PGHOST}" -lt 1 ] && PGHOST=localhost + check_accepted_names ${PGHOST} database_host + PGPORT=`echo -n ${db} | awk -F ';' '{print $3}'` + [ "${#PGPORT}" -lt 1 ] && PGPORT=5432 + check_int ${PGPORT} database_port + PGUSER=`echo -n ${db} | awk -F ';' '{print $4}'` + check_accepted_names ${PGUSER} database_user + PGPASSWORD=`echo -n ${db} | awk -F ';' '{print $5}'` + check_accepted_names ${PGPASSWORD} database_pw + DELCHECK=`echo -n ${db} | awk -F ';' '{print $6}'` + [ "${#DELCHECK}" = 0 ] || error 'field delimiter conflict: there may be a ";" in one of your database definitions (db/host/port/user/pw)' + SQL="SELECT template_code FROM language ;" + echo \ \ ${OK} + RES=`psql --pset tuples_only -h "${PGHOST}" -U "${PGUSER}" "${PGDATABASE}" -c "${SQL}"` || error "unable to connect to db "${PGDATABASE} + echo -e ' -> found '`mark "${RES}"` + echo \ \ ${OK} + LANGS=${LANGS}' '${RES} + done + + LANGS=`echo ${LANGS} | sed 's/\ /\n/g'|sort | uniq` + echo ' -> join language codes ...' + echo + echo + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + echo -e ' '${LANGS} + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo + echo ' I found the above listed language template_codes (see: System -> Languages -> List Languages)' + echo ' - you may add more template_codes by type in a [space] seperated list (e.g.: ru it fr)' + echo ' - or you may replace it with your own values by type in a [space] seperated list (e.g.: ru it fr)' + ask_yn ' add template_codes? [y/n/q]: ' + + if [ "${ANSWER}" = y ] ; then + echo -n ' type [space] seperated template_code list to add to current values: ' + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + read TMP_CO + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo -n ' list of template_codes is now: ' + LANGS=${LANGS}' '${TMP_CO} + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + echo -e ' '${LANGS} + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo \ \ ${OK} + fi + ANSWER=0 + + ask_yn ' replace the current template_codes? [y/n/q]: ' + + if [ "${ANSWER}" = y ] ; then + echo -n ' type [space] seperated template_code list to replace current values: ' + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + read TMP_CO + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo -n ' list of template_codes is now: ' + LANGS=${TMP_CO} + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + echo -e ' '${LANGS} + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo \ \ ${OK} + fi + ANSWER=0 + else + echo -n ' type [space] seperated template_code list (see: System -> Languages -> List Languages eg: de en fr): ' + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + read TMP_CO + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo -n ' list of template_codes is now: ' + LANGS=${TMP_CO} + [ "${NO_COLOR}" = 1 ] || echo -ne ${MARK} + echo -e ' '${LANGS} + [ "${NO_COLOR}" = 1 ] || echo -ne ${UNMARK} + echo \ \ ${OK} + fi + + echo + echo + echo -e ' your current language template_codes are: '`mark "${LANGS}"` + echo + echo + + # copy files and create links + + + + for now in ${FILE_LIST_FTEX} ; do + create_file cp ../f-tex/${now} ${now} + done + + for now in ${LANGS} ; do + echo -n ' -> check if language code '${now}' is present in translations.tex' + egrep '^[^%]*\\IfEndWith{\\docname}{_'${now}'}' translations.tex > /dev/null + if [ "$?" -gt 0 ] ;then + HINT=' edit '${TEMP_DIR}'/translations.tex -- no representation of template_code '${now} + echo ' [warning] '${HINT} + FEEDBACK=${FEEDBACK}' # '${HINT}'\n' + fi + echo \ \ ${OK} + done + + + for doc in ${DOC_TYPE_FTEX} ; do + create_file ln ./letter.tex ./${doc}.tex + for now in ${LANGS} ; do + create_file ln ./letter.tex ./${doc}_${now}.tex + done + done + + create_file ln ./sample_head.pdf ./letter_head.pdf + create_file ln ./sample.lco ./letter.lco + +fi + + + +if [ "${MODUL}" = "lp" ] ; then + + for now in ${FILE_LIST_LP} ; do + create_file cp ../lp/${now} ${now} + done + +fi + +echo +echo +echo -en ' '${FEEDBACK} +echo -e ' ################################' +echo +echo ' If there are warnings listed in the feedback box above' +echo ' this is totally ok if you know what you do' +echo +echo ' done -> enjoy' +echo ' ### please check "settings" in '`pwd`'letter.lco ' + + +# company +# address +# co_ustid +# email +# taxnumber +# tel +# fax diff --git a/templates/f-tex/translations.tex b/templates/f-tex/translations.tex new file mode 100644 index 000000000..aebdd394b --- /dev/null +++ b/templates/f-tex/translations.tex @@ -0,0 +1,198 @@ +% ---------------------------------------------------------- +% translations.tex +% Zentrale Uebersetzungsdatei f-tex +% +% Changelog: see gitlog + \newcommand{\ftTranslationsVersion}{1.0-u (16.11.2011)} +% +% Lizenz +% http://www.gnu.de/licenses/gpl-3.0.html +% +% Siehe ./README +% +% Autor: Wulf Coulmann scripts_at_gpl.coulmann.de +% +% +% ---------------------------------------------------------- + + +\begingroup + \makeatletter + \@latex@warning@no@line{ #### this is translations.tex \ftTranslationsVersion #####} +\endgroup + + +%%%%% Anleitung zum zufuegen neuer Sprachen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Am Beispiel Franzoesisch (fr) % +% - Es wird empfohlen die Datei translations.tex im Vorlagenordner % +% und _nicht_ in [lxo-home]/templates/f-tex zu aendern. % +% - Kopiere den Block % +% "\newcommand{\LoadDE}{" % +% bis zur schliessenden Klammer % +% "}" % +% und fuege ihn am Ende der Datei bei % +% "codeblock mit neuer Sprache hier einfuegen" % +% an % +% - uebersetze die deutschen Begriffe im neu eingefuegten Block in % +% die neue Sprache % +% - aendere den Kommandonamen entsprechend der Neuen Sprache % +% "\newcommand{\LoadFR} % +% - fuege am Ende der Datei eine neue Zeile mit dem neuen Sprachkuerzel % +% und dem neuen Funktionsnamen an. % +% "\IfEndWith{\docname}{_fr}{\loadFR}{} % +% - pruefe, ob lxo bereits ueber eine Konfiguration zu der neuen Sprache % +% verfuegt. Das Feld Vorlagenkuerzel muss den zur hier zugefuegten Sprache % +% passenden Wert enthalten (in unserem Beispiel "fr") % +% - rufe das script [lxo-home]/templates/f-tex/setup.sh erneut auf, um % +% sicherzustellen, dass die benoetigten Symlinks vorhanden sind. % +% - schicke die neue Version dieser Datei an % +% scripts_at_gpl.coulmann.de % +% damit in Zukunft die neue Sprache auch anderen Nutzern % +% von lxo zur Verfuegung steht % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + +% ===== de =========== +\newcommand{\loadDE}{ + + \renewcommand{\TitleInv}{Rechnung} + \newcommand{\TitleProforma}{Proformarechnung} + \newcommand{\TitleCreditNote}{Gutschrift} + \newcommand{\TitleSalesOrder}{Auftragsbestätigung} + \newcommand{\TitleSalesQuotation}{Angebot} + \newcommand{\TitleDelorder}{Lieferschein} + \newcommand{\TitlePicklist}{Sammelliste} + \newcommand{\TitlePurchaseOrder}{Bestellung} + \newcommand{\DelorderNumber}{Lieferscheinnummer} + \newcommand{\DeliveryAddress}{Lieferadresse} + \newcommand{\InvNumber}{Rechnungsnummer} + \newcommand{\CredNumber}{Gutschriftnummer} + \newcommand{\OrderNumber}{Auftragsnummer} + \newcommand{\RequestOrderNumber}{Bestellauftragsnummer} + \newcommand{\QuotationNumber}{Angebotsnummer} + \newcommand{\CustomerID}{Kundennummer} + \newcommand{\VendorID}{Lieferantennummer} + \newcommand{\DelDate}{Lieferdatum} + \newcommand{\ReqByTitle}{Lieferung bis} + \newcommand{\ValidUntil}{gültig bis} + \newcommand{\Date}{Datum} + \newcommand{\Pos}{Pos} + \newcommand{\Number}{Best Nr.} + \newcommand{\ItemNo}{Artikel} + \newcommand{\Count}{Anz} + \newcommand{\Unit}{Einh} + \newcommand{\Storage}{Lagerplatz} + \newcommand{\Take}{entnommen} + \newcommand{\Fee}{Einzelp} + \newcommand{\Total}{Total} + \newcommand{\Sum}{Gesamtbetrag} + \newcommand{\EbT}{Summe vor Steuern} + \newcommand{\Left}{Restbetrag} + \newcommand{\AlreadyPayed}{bereits gezahlt am} + \newcommand{\TabSubTotal}{Zwischensumme} + \newcommand{\TabCarry}{Übertrag} + \newcommand{\Dis}{Rab} + \newcommand{\TaxInc}{bereits enthalten: } + \newcommand{\PriceInclTax}{Alle Preise incl. Mehrwertsteuer} + \newcommand{\UstidTitle}{Ihre Umsatzsteueridentnummer:} + + + % Zahlungshinweise + \newcommand{\paymenthints}{ + + \IfSubStr{\docname}{Angebot}{ + Das Angebot hat 4 Wochen Gültigkeit.\\ + }{} + } + + \newcommand{\YourOrder}{ + \ifthenelse{\equal{\cusordnumber}{\leer}} + {} + {Ihre Bestellung {\bf\cusordnumber}}\\[0.5em] + } + +} + +% ===== uk oder en =========== +\newcommand{\loadUK}{ + + \renewcommand{\TitleInv}{Invoice} + \newcommand{\TitleProforma}{Pro Forma Invoice} + \newcommand{\TitleCreditNote}{Credit Note} + \newcommand{\TitleSalesOrder}{Sales Order} + \newcommand{\TitleSalesQuotation}{Sales Quotation} + \newcommand{\DelorderNumber}{delivery note no} + \newcommand{\DeliveryAddress}{delivery address} + \newcommand{\TitleDelorder}{Delivery Note} + \newcommand{\TitlePicklist}{Pick List} + \newcommand{\TitlePurchaseOrder}{Purchase Order} + \newcommand{\InvNumber}{invoice number} + \newcommand{\CredNumber}{credit number} + \newcommand{\OrderNumber}{order number} + \newcommand{\RequestOrderNumber}{purchase order no.} + \newcommand{\QuotationNumber}{quotation no} + \newcommand{\CustomerID}{customer id} + \newcommand{\VendorID}{vendor id} + \newcommand{\DelDate}{date of delivery} + \newcommand{\ReqByTitle}{required by} + \newcommand{\ValidUntil}{valid until} + \newcommand{\Date}{date} + \newcommand{\Pos}{pos} + \newcommand{\Number}{item id} + \newcommand{\ItemNo}{item} + \newcommand{\Count}{count} + \newcommand{\Unit}{unit} + \newcommand{\Storage}{location} + \newcommand{\Take}{taken} + \newcommand{\Fee}{fee} + \newcommand{\Total}{total} + \newcommand{\Sum}{total amount} + \newcommand{\EbT}{total without taxes} + \newcommand{\Left}{residue} + \newcommand{\AlreadyPayed}{already payed at} + \newcommand{\TabSubTotal}{subtotal} + \newcommand{\TabCarry}{carry} + \newcommand{\Dis}{dis} + \newcommand{\TaxInc}{already included: } + \newcommand{\PriceInclTax}{Prices incl. tax} + \newcommand{\UstidTitle}{Your VAT number:} + + % Zahlungshinweise Rechnung + \newcommand{\paymenthints}{ + \IfSubStr{\docname}{Angebot}{ + The offer is valid for 4 weeks.\\ + }{} + } + + \newcommand{\YourOrder}{ + \ifthenelse{\equal{\cusordnumber}{\leer}} + {} + {Your Order Number {\bf\cusordnumber}}\\[0.5em] + } + +} + +% ====== neuen Sprache ================================ + + % codeblock mit neuer Sprache hier einfuegen + + +% ====== Ende Sprachblock ========= +\newcommand{\checkVal}{unknowen} +\newcommand{\TitleInv}{\checkVal} + + +\IfEndWith{\docname}{_de}{\loadDE}{} +\IfEndWith{\docname}{_uk}{\loadUK}{} +\IfEndWith{\docname}{_en}{\loadUK}{} +% neue Zeile mit dem neuen Sprachkuerzel und dem neuen Funktionsnamen hier anfuegen + + + +% ====== unterhalb dieser Zeile nichts aendern ========================== + +% defaultsprache + \ifthenelse{\equal{\TitleInv}{\checkVal}}{\loadDE}{} + diff --git a/templates/f-tex/xstring.sty b/templates/f-tex/xstring.sty new file mode 100644 index 000000000..cf55c27b5 --- /dev/null +++ b/templates/f-tex/xstring.sty @@ -0,0 +1,704 @@ +% __________________________________________________ +% | | +% | | +% | xstring v1.0 | +% | | +% | July, 4th 2008 | +% | | +% |__________________________________________________| +% +% This is xtring.sty +% +% Christian Tellechea 2008 +% email : unbonpetit@gmail.com +% ------------------------------------------------------------------- +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% of this license or (at your option) any later version. +% The latest version of this license is in +% +% http://www.latex-project.org/lppl.txt +% +% and version 1.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% ------------------------------------------------------------------- +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Christian Tellechea +% +% This work consists of the files +% xstring.sty (this file) +% readme.txt +% xstring_doc_fr.tex, xstring_doc_fr.pdf (manual in french) +% xstring_doc_en.tex, xstring_doc_en.pdf (manual in english) +% xstring_test.tex, xstring_test.pdf (test file) +% +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{xstring}[2008/07/04 v1.0 Extended macros for strings. C Tellechea] + +% Messages pour situations particulières +\newcommand\@xs@BadNumArg {\PackageInfo{xstring}{numerical argument out of range}} +\newcommand\@xs@ArgNotFound {\PackageInfo{xstring}{substring not found in string}} +\newcommand\@xs@ArgEmpty {\PackageInfo{xstring}{empty argument}} + +% Ouvre un groupe où les catcodes sont à 12 et à 10 pour les espaces +% ensuite, appelle \@xs@ReadVerb qui lit un argument entre délimiteurs verb +\newcommand\@xs@MakeVerb{% lit 1 argument et le transforme en verb + \begingroup% groupe où les catcodes sont à 12 pour la lecture suivante + \let\do\@makeother + \dospecials% on entre dans le mode verb + \obeyspaces% et on tient compte des espaces + \@xs@ReadVerb}% et on va lire l'argument + +% Définit \@xs@ReadVerb qui lit un argument entre délimiteurs verb +\newcommand\setverbdelim[1]{% définit quel est le délimiteur de verb + \@xs@StrLen{#1}[\@len@verbdelim]% + \ifnum\@len@verbdelim=\@ne + \else + \PackageWarning{xstring}{verb delimiter is not a single char}% + \fi + \def\@xs@ReadVerb##1#1##2#1{% lit ##2 qui est entre les délimiteurs de verb + \endgroup% on ferme le groupe + \@xs@afterreadverb{##2}}}% on appelle l'exécution de fin + +% Assigne l'argument entre délimiteur verb dans la sc #1 +\newcommand\verbtocs[1]{% + \def\@xs@afterreadverb##1{\edef#1{##1}}% + \@xs@MakeVerb} + +% A l'aide d'un pont d'\expandafter, développe d'un niveau toutes +% les sc de #1 puis et assigne le résultat à \result +\def\@xs@expandallonelevel#1#2\@nil{% + \expandafter\expandafter\expandafter\def% plein d'expandafter + \expandafter\expandafter\expandafter\result% pour développer #1 d'un niveau + \expandafter\expandafter\expandafter{\expandafter\result#1}% et l'ajouter à \result + \ifx\@empty#2\@empty\else\@xs@expandallonelevel#2\@nil\fi}% s'il reste des sc, on boucle + +% \scancs développe #3 autant de fois que spécifié en #1 +% puis le développement obtenu est verbatimisé. +% On utilise \@xs@expandalltodepth autant de fois que #1 le spécifie +% puis on invoque \detokenize à la fin +\newcount\depth@scancs +\newcommand\scancs{% + \@ifstar% + {\PackageWarning{xstring}{if third argument or its expansion have braces or spaces, they will be removed when scanned! Use starred \string\scancs* macro with care}% + \def\@testornot{\@notestcs}% + \@xs@scancs}% + {\def\@testornot{\@testcs}% + \@xs@scancs}} +\newcommand\@xs@scancs[3][1]{% +% #1 : profondeur à développer avant de verbatimiser +% #2 : nom de la sc recevant la chaine verb +% #3 : nom de la sc à développer et à transformer en verb + \depth@scancs\z@ + \def\@notestcs##1\@nil{\relax}% + \def\@testcs##1##2\@nil{% + \ifx\@empty##2\@empty + \else% si la séquence de contrôle n'est pas seule, on gueule + \PackageError{xstring}{third argument or its expansion is not a single control sequence! Use \string\scancs* instead of \string\scancs (see manual).}% + \fi}% + \def\@xs@expandalltodepth##1\@nil{% développe de #1 niveaux toutes les sc de #3 et l'assigne à \the@result + \def\result{}% + \ifnum\depth@scancs<#1% tant que la profondeur de développement n'est pas atteinte + \@testornot##1\@nil% on teste éventuellement si le développement comporte 1 seule sc + \expandafter\@xs@expandallonelevel\the@result\@nil% on développe tout d'un niveau + \expandafter\def\expandafter\the@result\expandafter{\result}% + \advance\depth@scancs\@ne + \expandafter\@xs@expandalltodepth\the@result\@nil% et on recommence + \fi}% + \def\the@result{#3}% + \@xs@expandalltodepth#3\@nil + \expandafter\def\expandafter#2\expandafter{\detokenize\expandafter{\the@result}}} + +% Cette macro développe #2 au maximum (ce qui doit donner du texte), +% puis le transforme en token et l'assigne à #1 +% On ouvre un groupe dans lequel un \@nil est inséré à la fin du fichier virtuel +% lu avec \scantokens. Ce \@nil sert à l'argument délimité de \@AssignResult +\newcommand\tokenize[2]{% + \begingroup + \expandafter\@xs@def\expandafter\the@text\expandafter{#2}% on développe en accord avec \fullexpandarg ou \noexpandarg + \def\@AssignResult##1\@nil{\def#1{##1}}% on assigne en tenant compte du \@nil qui vient de la fin du fichier virtuel + \everyeof{\@nil}% met un \@nil à la fin du fichier virtuel + \endlinechar\m@ne + \expandafter\expandafter\expandafter\endgroup% on retarde la fermeture du groupe + \expandafter\@AssignResult\scantokens\expandafter{\the@text}}% pout faire l'assignation + +% Macro très simple qui assigne ou affiche le résultat, selon la présence +% ou non de #2 qui est l'argument optionnel venant en dernière position des macros +\newcommand\@xs@ReturnResult[2]{% + \expandafter\ifx\expandafter\@empty\detokenize{#2}\@empty% pas de nom ? + #1% on affiche #1 + \else% il y a un nom donc + \edef#2{#1}% on met #1 dans #3 avec edef + \fi} + +% Pas d'expansion des arguments +\newcommand\normalexpandarg{% + \let\@xs@def\def% on définit\@call avec \def + \let\@xs@expand\@empty}% et on neutralise \@xs@expand + +% Expansion des arguments +\newcommand\fullexpandarg{% + \let\@xs@def\edef% on définit\@call avec \edef + \let\@xs@expand\noexpand}% et on utilise \noexpand + +% Cette macro interne enlève le 1er caractère de la chaine passée en argument +\def\@xs@RemoveFirst#1[#2]{% + \ifx\@empty#1\@empty + \edef#2{}% + \else + \@xs@IfBeginWith{#1}{ }% + {\@xs@StrBehind[1]{#1}{ }[#2]}% + {\def\@xs@RemoveFirst@ii##1##2\@nil{\edef#2{##2}}% + \@xs@RemoveFirst@ii#1\@nil}% + \fi} + +% Cette macro interne renvoie le 1er caractère de la chaine passée en argument +\def\@xs@ReturnFirst#1[#2]{% + \ifx\@empty#1\@empty% + \edef#2{}% + \else + \@xs@IfBeginWith{#1}{ }% + {\edef#2{ }}% + {\def\@xs@ReturnFirst@ii##1##2\@nil{\edef#2{##1}}% + \@xs@ReturnFirst@ii#1\@nil}% + \fi} + +% Cette macro interne est utilisée dans les macros étoilées pour : +% 1) développer l'argument selon qu'on a choisit \fullexpandarg +% ou \normalexpandarg, et ceci à l'aide de la macro \@xs@def +% 2) Ensuite, on détokenize ce développement de façon n'avoir plus que +% des catcodes de 10 pour les espaces et 12 pour le reste. +\newcommand\@xs@expand@and@detokenize[2]{% + \@xs@def#1{#2}% on développe #2 selon \fullexpandarg ou \normalexpandarg + \edef#1{\detokenize\expandafter{#1}}}% puis on détokenize et on assigne à #1 + +% Cette macro teste si une chaine (#2) en contient au moins n(#1) fois une autre (#3) +% Pour cela, on teste "ce qu'il reste" après #2. On construit une récursivité sur le +% compteur d'occurences \Occurrence@IfSubStr. Si "ce qu'il reste" est vide avant d'atteindre +% l'occurence voulue, le test est négatif, sinon on poursuit par récursivité sur "ce qu'il reste" +% jusqu'à l'occurrence voulue. Si l'on atteint l'occurrence voulue, le test est positif. +% On utilise la séquence de contrôle non définie \@delimit pour éviter un effet +% indésirable qui ferait que \IfSubStr{a}{aa}{V}{F} renverrait V +\newcommand\IfSubStr{\@ifstar\@xs@IfSubStr@@\@xs@IfSubStr@}% +\newcommand\@xs@IfSubStr@@[3][1]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \edef\@call{\noexpand\@xs@IfSubStr[\@xs@expand#1]{\xsarg@a}{\xsarg@b}}% + \@call} +\newcommand\@xs@IfSubStr@[3][1]{% + \@xs@def\@call{\@xs@expand\@xs@IfSubStr[#1]{#2}{#3}}% + \@call} +\newcount\Occurrence@IfSubStr +\def\@xs@IfSubStr[#1]#2#3{% +% est ce que la chaine #2 contient au moins #1 fois la sous chaine #3 ? + \ifnum#1<\@ne% on gère les cas spéciaux + \def\@xsresult@IfSubStr{\expandafter\@secondoftwo}% #1<1 -> on exécute #5 + \else + \ifx\@empty#3\@empty% + \def\@xsresult@IfSubStr{\expandafter\@secondoftwo}% si #3 est vide -> on écécute #5 + \else + \Occurrence@IfSubStr\z@ + \def\@xs@IfSubStr@i##1#3##2\@nil{% + \advance\Occurrence@IfSubStr\@ne + \ifx\@empty##2\@empty%% qu'y a t-il apès la sous chaine ? + \def\@xsresult@IfSubStr{\expandafter\@secondoftwo}% rien -> on exécute #5 + \else% si ce qu'il est reste n'est pas vide + \ifnum\Occurrence@IfSubStr<#1% tant que le nombre d'occurrence n'est pas atteint + \@xs@IfSubStr@i##2\@nil% on recommence + \else + \def\@xsresult@IfSubStr{\expandafter\@firstoftwo}% nombre d'occurrences atteint : on renvoie #4 + \fi + \fi}% + \@xs@IfSubStr@i#2\@delimit#3\@nil% \@delimit pour éviter le cas de \IfSubStr{a}{aa}{V}{F} qui renverrait V + \fi + \fi + \@xsresult@IfSubStr} + +\newcommand\IfBeginWith{\@ifstar\@xs@IfBeginWith@@\@xs@IfBeginWith@}% +\newcommand\@xs@IfBeginWith@@[2]{% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \@xs@expand@and@detokenize{\xsarg@b}{#2}% + \edef\@call{\noexpand\@xs@IfBeginWith{\xsarg@a}{\xsarg@b}} + \@call} +\newcommand\@xs@IfBeginWith@[2]{% + \@xs@def\@call{\@xs@expand\@xs@IfBeginWith{#1}{#2}}% + \@call} +\newcommand\@xs@IfBeginWith[2]{% + \@xs@IfSubStr[1]{#1}{#2}% + {\ifx\@empty#2\@empty% + \def\@xs@IfBeginWith@i##1\@nil{\expandafter\@firstoftwo}% si #2 est vide, on renvoie vrai + \else + \def\@xs@IfBeginWith@i##1#2##2\@nil{% qu'y a t-il avant #2 ? + \ifx\@empty##1\@empty + \expandafter\@firstoftwo% rien, donc #2 est au début, on renvoie vrai + \else + \expandafter\@secondoftwo + \fi}% + \fi}% + {\def\@xs@IfBeginWith@i##1\@nil{\expandafter\@secondoftwo}}% si #2 n'est pas dans #1, on renvoie faux + \@xs@IfBeginWith@i#1\@delimit#2\@nil} + +\newcommand\IfEndWith{\@ifstar\@xs@IfEndWith@@\@xs@IfEndWith@}% +\newcommand\@xs@IfEndWith@@[2]{% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \@xs@expand@and@detokenize{\xsarg@b}{#2}% + \edef\@call{\noexpand\@xs@IfEndWith{\xsarg@a}{\xsarg@b}} + \@call} +\newcommand\@xs@IfEndWith@[2]{% + \@xs@def\@call{\@xs@expand\@xs@IfEndWith{#1}{#2}}% + \@call} +\newcommand*\@xs@IfEndWith[2]{% +% Est ce que la chaine #1 finit par la chaine #2 ? + \@xs@IfSubStr[1]{#1}{#2}% + {\ifx\@empty#2\@empty% si #2 est vide -> test vrai + \def\@xs@remove@begining##1\@nil{\expandafter\@firstoftwo}% + \else + \def\@xs@remove@begining##1#2##2\@nil{% on isole ce qui est après #2, la chaine restante ##2 + \@xs@IfSubStr[1]{##2}{#2}% tant que #2 est dans la chaine restante.. + {\@xs@remove@begining##2\@nil}% ...on recommence + {\ifx\@empty##2\@empty% sinon, on regarde ce qui reste + \expandafter\@firstoftwo% rien -> test vrai + \else + \expandafter\@secondoftwo% quelque chose -> test faux + \fi + }% + }% + \fi}% + {\def\@xs@remove@begining##1\@nil{\expandafter\@secondoftwo}}% si #2 n'est pas dans #1 -> test faux + \@xs@remove@begining#2#1\@nil} + +\newcount\Occurrence@StrBefore +% Renvoie ce qui est à gauche de l'occurence n°#1 de la sous chaine #3 dans la chaine #2 +\newcommand\StrBefore{\@ifstar\@xs@StrBefore@@\@xs@StrBefore@} +\newcommand\@xs@StrBefore@@[3][1]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrBefore[\@xs@expand#1]{\xsarg@a}{\xsarg@b}}{}}% + \@call} +\newcommand\@xs@StrBefore@[3][1]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrBefore[#1]{#2}{#3}}{}}% + \@call} +\def\@xs@StrBefore[#1]#2#3[#4]{% + \ifx\@empty#3\@empty% + \@xs@ArgNotFound% warning + \edef\@xs@result@StrBefore{}% + \else + \edef\@xs@result@StrBefore{}% resultat nul pour l'instant + \Occurrence@StrBefore\z@ + \def\@xs@StrBefore@i##1#3##2\@nil{% + \advance\Occurrence@StrBefore\@ne% on incrémente + \ifx\@empty##2\@empty% pas trouvé ? + \@xs@ArgNotFound% warning + \edef\@xs@result@StrBefore{}% renvoie vide + \else + \ifnum\Occurrence@StrBefore<#1% tant que c'est pas la bonne occurrence + \edef\@xs@result@StrBefore{\@xs@result@StrBefore##1#3}% on ajoute le début au résultat final + \@xs@StrBefore@i##2\@nil% on recommence avec la chaine restante + \else + \edef\@xs@result@StrBefore{\@xs@result@StrBefore##1}% on n'ajoute pas la chaine frontière #3 la dernière fois ! + \fi + \fi}% + \@xs@StrBefore@i#2\@delimit#3\@nil% + \fi + \@xs@ReturnResult{\@xs@result@StrBefore}{#4}} + +\newcount\Occurrence@StrBehind +% Renvoie ce qui est à droite de l'occurence n°#1 de la sous chaine #3 dans la chaine #2 +\newcommand\StrBehind{\@ifstar\@xs@StrBehind@@\@xs@StrBehind@} +\newcommand\@xs@StrBehind@@[3][1]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrBehind[\@xs@expand#1]{\xsarg@a}{\xsarg@b}}{}}% + \@call} +\newcommand\@xs@StrBehind@[3][1]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrBehind[#1]{#2}{#3}}{}}% + \@call} +\def\@xs@StrBehind[#1]#2#3[#4]{% + \ifx\@empty#3\@empty% + \@xs@ArgNotFound% warning + \edef\@xs@result@StrBehind{}% + \else + \Occurrence@StrBehind\z@ + \def\@xs@StrBehind@i##1#3##2\@nil{% + \advance\Occurrence@StrBehind\@ne% on incrémente + \ifnum\Occurrence@StrBehind<#1% tant que c'est pas la bonne occurrence + \@xs@IfSubStr[1]{##2}{#3}% tant que la chaine restante contient #3 + {\@xs@StrBehind@i##2\@nil}% on recommence avec la chaine restante + {\@xs@ArgNotFound% sinon, info + \edef\@xs@result@StrBehind{}}% et on renvoie vide + \else + \edef\@xs@result@StrBehind{##2}% on renvoie la chaine restante + \fi}% + \@xs@IfSubStr[1]{#2}{#3}% + {\@xs@StrBehind@i#2\@nil}% + {\@xs@ArgNotFound% warning + \edef\@xs@result@StrBehind{}}% + \fi + \@xs@ReturnResult{\@xs@result@StrBehind}{#4}} + +\newcommand\IfSubStrBefore{\@ifstar\@xs@IfSubStrBefore@@\@xs@IfSubStrBefore@} +% est ce que l'occurrence #1 de la sous chaine #4 se trouve avant +% l'occurrence n°#2 de la sous chaine #5 dans la chaine #3? +\newcommand\@xs@IfSubStrBefore@@[4][1,1]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \@xs@expand@and@detokenize{\xsarg@c}{#4}% + \edef\@call{\noexpand\@xs@IfSubStrBefore[\@xs@expand#1]{\xsarg@a}{\xsarg@b}{\xsarg@c}}% + \@call} +\newcommand\@xs@IfSubStrBefore@[4][1,1]{% + \@xs@def\@call{\@xs@expand\@xs@IfSubStrBefore[#1]{#2}{#3}{#4}}% + \@call} +\def\@xs@IfSubStrBefore[#1,#2]#3#4#5{% + \@xs@StrPosition[#2]{#3}{#5}[\@xs@posMax@IfSubStrBefore]% on trouve les positions + \@xs@StrPosition[#1]{#3}{#4}[\@xs@posPattern@IfSubStrBefore]% + \ifnum\@xs@posMax@IfSubStrBefore<\@ne% + \def\@xs@result@IfSubStrBefore{\expandafter\@secondoftwo}% si pas trouvé #5 : 0 renvoie faux + \else + \ifnum\@xs@posPattern@IfSubStrBefore<\@ne% + \def\@xs@result@IfSubStrBefore{\expandafter\@secondoftwo}% si pas trouvé #4 : 0 renvoie faux + \else + \ifnum\@xs@posPattern@IfSubStrBefore<\@xs@posMax@IfSubStrBefore% + \def\@xs@result@IfSubStrBefore{\expandafter\@firstoftwo}% + \else + \def\@xs@result@IfSubStrBefore{\expandafter\@secondoftwo}% + \fi + \fi + \fi + \@xs@result@IfSubStrBefore} + +% Est ce que l'occurrence #1 de la sous chaine #4 se trouve avant +% l'occurrence n°#2 de la sous chaine #5 dans la chaine #3? +\newcommand\IfSubStrBehind{\@ifstar\@xs@IfSubStrBehind@@\@xs@IfSubStrBehind@} +\newcommand\@xs@IfSubStrBehind@@[4][1,1]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \@xs@expand@and@detokenize{\xsarg@c}{#4}% + \edef\@call{\noexpand\@xs@IfSubStrBehind[\@xs@expand#1]{\xsarg@a}{\xsarg@b}{\xsarg@c}}% + \@call} +\newcommand\@xs@IfSubStrBehind@[4][1,1]{% + \@xs@def\@call{\@xs@expand\@xs@IfSubStrBehind[#1]{#2}{#3}{#4}}% + \@call} +\def\@xs@IfSubStrBehind[#1,#2]#3#4#5{% + \@xs@StrPosition[#2]{#3}{#5}[\@xs@posMax@IfSubStrBehind]% on trouve les positions + \@xs@StrPosition[#1]{#3}{#4}[\@xs@posPattern@IfSubStrBehind]% + \ifnum\@xs@posMax@IfSubStrBehind<1\relax% + \def\@xs@result@IfSubStrBehind{\expandafter\@secondoftwo}% si pas trouvé : 0 renvoie faux + \else + \ifnum\@xs@posPattern@IfSubStrBehind<1% + \def\@xs@result@IfSubStrBehind{\expandafter\@secondoftwo}% si pas trouvé : 0 renvoie faux + \else + \ifnum\@xs@posPattern@IfSubStrBehind>\@xs@posMax@IfSubStrBehind% + \def\@xs@result@IfSubStrBehind{\expandafter\@firstoftwo}% + \else + \def\@xs@result@IfSubStrBehind{\expandafter\@secondoftwo}% + \fi + \fi + \fi + \@xs@result@IfSubStrBehind} + +\newcount\Gobble@StrBetween +% Renvoie ce qui est strictement compris entre les occurrences n°#1 et n°#2 +% des chaines #4 et #5 dans la chaine #3 +\newcommand\StrBetween{\@ifstar\@xs@StrBetween@@\@xs@StrBetween@} +\newcommand\@xs@StrBetween@@[4][1,1]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \@xs@expand@and@detokenize{\xsarg@c}{#4}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrBetween[\@xs@expand#1]{\xsarg@a}{\xsarg@b}{\xsarg@c}}{}}% + \@call} +\newcommand\@xs@StrBetween@[4][1,1]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrBetween[#1]{#2}{#3}{#4}}{}}% + \@call} +\def\@xs@StrBetween[#1,#2]#3#4#5[#6]{% + \ifx\@empty#5\@empty% + \edef\@xs@StringBefore@StrBetween{}% + \else + \@xs@StrBefore[#2]{#3}{#5}[\@xs@StringBefore@StrBetween]% on extrait ce qui est à gauche de l'occurrence de #5 + \@xs@StrPosition[#1]{#3}{#4}[\@xs@Pos@StrBetween]% position de l'occurrence de #3 + \Gobble@StrBetween\@xs@Pos@StrBetween% + \@xs@StrLen{#4}[\@xs@Pos@StrBetween]% + \advance\Gobble@StrBetween\@xs@Pos@StrBetween% on lui ajoute la longueur de #3 + \advance\Gobble@StrBetween\m@ne% et on enlève 1 + \expandafter\expandafter\expandafter\@xs@StrGobbleLeft% + \expandafter\expandafter\expandafter{\expandafter\@xs@StringBefore@StrBetween\expandafter}% + \expandafter{\Gobble@StrBetween}[\@xs@result@StrBetween]% pour manger ce nombre de caractère au début de \@xs@StringBefore@StrBetween + \fi + \@xs@ReturnResult{\@xs@result@StrBetween}{#6}} + +\newcount\Occurrence@StrSubstitute +% Remplace les #1 premières occurences de la chaine #3 +% par la chaine #4 dans la chaine #2 +\newcommand\StrSubstitute{\@ifstar\@xs@StrSubstitute@@\@xs@StrSubstitute@} +\newcommand\@xs@StrSubstitute@@[4][0]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \@xs@expand@and@detokenize{\xsarg@c}{#4}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrSubstitute[\@xs@expand#1]{\xsarg@a}{\xsarg@b}{\xsarg@c}}{}}% + \@call} +\newcommand\@xs@StrSubstitute@[4][0]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrSubstitute[#1]{#2}{#3}{#4}}{}}% + \@call} +\def\@xs@StrSubstitute[#1]#2#3#4[#5]{% + \Occurrence@StrSubstitute\z@ + \ifx\@empty#3\@empty% si #3 est vide, on ne fait rien + \@xs@ArgEmpty% warning + \edef\@result@StrSubstitute{#2}% + \else + \edef\@result@StrSubstitute{}% on initialise à vide, histoire d'enlever le statut undefined + \def\@xs@StrSubstitute@i##1#3##2\@nil{% + \edef\@result@StrSubstitute{\@result@StrSubstitute##1#4}% on recopie jusqu'à la 1ere occurrence, et on remplace #3 par #4 + \ifnum#1>\z@% si on compte les occurrences + \advance\Occurrence@StrSubstitute\@ne% on incrémente le compteur + \@xs@IfSubStr[1]{##2}{#3}% tant que la chaine restante contient #3 + {\ifnum\Occurrence@StrSubstitute<#1% tant qu'on n'a pas atteint la bonne occurrence, + \@xs@StrSubstitute@i##2\@nil% on recommence + \else + \edef\@result@StrSubstitute{\@result@StrSubstitute##2}% l'occurrence est atteinte : on rajoute ce qui reste + \fi}% + {\edef\@result@StrSubstitute{\@result@StrSubstitute##2}}% si on ne peut plus substituter, on rajoute ce qui reste + \else% ici , on ne compte pas les occurrences, donc... + \@xs@IfSubStr[1]{##2}{#3}% ...tant que la chaine restante contient #3 + {\@xs@StrSubstitute@i##2\@nil}% on recommence + {\edef\@result@StrSubstitute{\@result@StrSubstitute##2}}% si on ne peut plus substituter, on rajoute ce qui reste + \fi}% + \@xs@IfSubStr[1]{#2}{#3}% + {\@xs@StrSubstitute@i#2\@nil}% si #2 contient #3, on exécute la macro + {\edef\@result@StrSubstitute{#2}}% sinon, on renvoie la chaine #2 + \fi + \@xs@ReturnResult{\@result@StrSubstitute}{#5}} + +% Supprime les #1 premières occurrences de #3 dans #2 +\newcommand\StrDel{\@ifstar\@xs@StrDel@@\@xs@StrDel@} +\newcommand\@xs@StrDel@@[3][0]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrSubstitute[\@xs@expand#1]{\xsarg@a}{\xsarg@b}{}}{}}% + \@call} +\newcommand\@xs@StrDel@[3][0]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrSubstitute[#1]{#2}{#3}{}}{}}% + \@call} + +\newcount\Length@StrLen +% Compte combien de caractères contient la chaine #1 ? +\newcommand\StrLen{\@ifstar\@xs@StrLen@@\@xs@StrLen@} +\newcommand\@xs@StrLen@@[1]{% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrLen{\xsarg@a}}{}}% + \@call} +\newcommand\@xs@StrLen@[1]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrLen{#1}}{}}% + \@call} +% Macro qui compte le nombre de caractères de son argument #1 +\def\@xs@StrLen@i#1\@nil{% + \ifx\@empty#1\@empty% tant que #1 n'est pas vide ... + \else + \advance\Length@StrLen\@ne% ...on ajoute 1 à la longueur + \@xs@IfBeginWith{#1}{ }% et on recommence après avoir enlevé le 1er caractère (on distingue le cas où c'est un espace) + {\@xs@StrBehind[1]{#1}{ }[\@xs@result@StrLen]% + \expandafter\@xs@StrLen@i\@xs@result@StrLen\@nil}% + {\expandafter\@xs@StrLen@i\@xs@RemoveFirst@StrLen#1\@nil\@nil}% + \fi}% +% Macro qui enlève le 1er caractère de son argument +\def\@xs@RemoveFirst@StrLen#1#2\@nil{#2}% +% Macro principale +\def\@xs@StrLen#1[#2]{% +% Renvoie la longueur de la chaine #1 + \Length@StrLen\z@ + \@xs@StrLen@i#1\@nil% + \expandafter\@xs@ReturnResult\expandafter{\the\Length@StrLen}{#2}} + +\newcount\Position@StrMid +\newcommand\StrMid{\@ifstar\@xs@StrMid@@\@xs@StrMid@} +\newcommand\@xs@StrMid@@[3]{% + \edef\@StrMid@First{\@xs@expand#2}\edef\@StrMid@Last{\@xs@expand#3}% position début et fin + \ifnum#2>#3\@xs@BadNumArg\fi + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrMid{\xsarg@a}}{}}% + \@call} +\newcommand\@xs@StrMid@[3]{% + \edef\@StrMid@First{\@xs@expand#2}\edef\@StrMid@Last{\@xs@expand#3}% position début et fin + \ifnum#2>#3\@xs@BadNumArg\fi + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrMid{#1}}{}}% + \@call} +% cette sous macro supprime le nombre de caractère nécessaires +% à la gauche de son argument, et renvoie le résultat dans \@result@Mid@Gobble +\def\@xs@Mid@Gobble#1\@nil{% enlève #2 caractères à gauche de ##1 + \advance\Position@StrMid\@ne + \ifnum\Position@StrMid=\@StrMid@First% si on a atteint la position + \edef\@result@Mid@Gobble{#1}% on renvoie ce qui reste + \else% sinon + \@xs@RemoveFirst{#1}[\@Mid@remain]% on enlève un caractère + \expandafter\@xs@Mid@Gobble\@Mid@remain\@nil% et on recommence + \fi}% +% cette sous macro prend le nombre de caractères nécessaires +% à la gauche de son argument, et renvoie le résultat dans \@final@Result +\def\@xs@Mid@Concat#1\@nil{% + \@xs@ReturnFirst{#1}[\@Char@to@add]% prend le 1er caractère + \edef\@final@Result{\@final@Result\@Char@to@add}% l'ajoute au résultat final + \@xs@RemoveFirst{#1}[\@remain@StrMid]% puis l'enlève de la chaine + \ifnum\Position@StrMid<\@StrMid@Last% si pas encore fini + \advance\Position@StrMid\@ne% on incrémente et + \expandafter\@xs@Mid@Concat\@remain@StrMid\@nil% on recommence + \fi}% +\def\@xs@StrMid#1[#2]{% +% renvoie la sous chaine de #1 comprise entre les positions \@StrMid@First et \@StrMid@Last + \@xs@StrLen{#1}[\@len@StrMid]% + \ifnum\@StrMid@First>\@StrMid@Last% mauvais ordre ? + \@xs@ReturnResult{}{#2}% on renvoie rien + \else + \ifnum\@StrMid@Last<\@ne% si position fin trop petite + \@xs@ReturnResult{}{#2}% on renvoie rien + \else + \ifnum\@StrMid@First<\@ne% 1ère position trop petite ? + \edef\@StrMid@First{1}% on limite à 1 + \@xs@BadNumArg% avertissement + \fi + \ifnum\@StrMid@Last>\@len@StrMid% dernière position trop grande ? + \edef\@StrMid@Last{\@len@StrMid}% on limite à la longueur de la chaine + \@xs@BadNumArg% avertissement + \fi + \Position@StrMid\z@ + \@xs@Mid@Gobble#1\@nil% on supprime ce qu'il faut à gauche + \edef\@final@Result{}% rien dans le résultat final pour l'instant + \expandafter\@xs@Mid@Concat\@result@Mid@Gobble\@nil% on prend les caractères qu'il faut à gauche + \expandafter\@xs@ReturnResult\expandafter{\@final@Result}{#2}% + \fi + \fi} + +\newcommand\StrGobbleLeft{\@ifstar\@xs@StrGobbleLeft@@\@xs@StrGobbleLeft@} +% supprime #2 caractères à gauche dans la chaine #1 +\newcommand\@xs@StrGobbleLeft@@[2]{% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrGobbleLeft{\xsarg@a}{\@xs@expand#2}}{}}% + \@call} +\newcommand\@xs@StrGobbleLeft@[2]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrGobbleLeft{#1}{#2}}{}}% + \@call} +\def\@xs@StrGobbleLeft#1#2[#3]{% + \edef\@StrMid@First{\numexpr#2+1}% + \@xs@StrLen{#1}[\@StrMid@Last]% + \@xs@StrMid{#1}[\@xs@result@StrGobbleLeft]% + \@xs@ReturnResult{\@xs@result@StrGobbleLeft}{#3}} + +% extrait de #1 la chaine à gauche de longueur #2 +\newcommand\StrLeft{\@ifstar\@xs@StrLeft@@\@xs@StrLeft@} +\newcommand\@xs@StrLeft@@[2]{% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrLeft{\xsarg@a}{\@xs@expand#2}}{}}% + \@call} +\newcommand\@xs@StrLeft@[2]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrLeft{#1}{#2}}{}}% + \@call} +\def\@xs@StrLeft#1#2[#3]{% + \edef\@StrMid@First{1}% + \ifnum#2<0\@xs@BadNumArg\fi% avertissement + \edef\@StrMid@Last{#2}% + \@xs@StrMid{#1}[\@xs@result@@StrLeft]% + \@xs@ReturnResult{\@xs@result@@StrLeft}{#3}} + +% supprime #2 caractères à droite dans la chaine #1 +\newcommand\StrGobbleRight{\@ifstar\@xs@StrGobbleRight@@\@xs@StrGobbleRight@} +\newcommand\@xs@StrGobbleRight@@[2]{% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrGobbleRight{\xsarg@a}{\@xs@expand#2}}{}}% + \@call} +\newcommand\@xs@StrGobbleRight@[2]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrGobbleRight{#1}{#2}}{}}% + \@call} +\def\@xs@StrGobbleRight#1#2[#3]{% + \@xs@StrLen{#1}[\@Result@Length]% + \ifnum#2>\@Result@Length\@xs@BadNumArg\fi% avertissement + \edef\@StrMid@First{1}% + \edef\@StrMid@Last{\numexpr\@Result@Length-#2}% + \@xs@StrMid{#1}[\@xs@result@StrGobbleRight]% + \@xs@ReturnResult{\@xs@result@StrGobbleRight}{#3}} + +% renvoie #2 caractères à la droite de la chaine #1 +\newcommand\StrRight{\@ifstar\@xs@StrRight@@\@xs@StrRight@} +\newcommand\@xs@StrRight@@[2]{% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrRight{\xsarg@a}{#2}}{}}% + \@call} +\newcommand\@xs@StrRight@[2]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrRight{#1}{#2}}{}}% + \@call} +\def\@xs@StrRight#1#2[#3]{% + \ifnum#2<0\@xs@BadNumArg\fi% avertissement + \@xs@StrLen{#1}[\@StrMid@Last]% + \edef\@StrMid@First{\numexpr\@StrMid@Last+1-#2}% + \@xs@StrMid{#1}[\@xs@result@StrMid]% + \@xs@ReturnResult{\@xs@result@StrMid}{#3}} + +\newcommand\StrChar{\@ifstar\@xs@StrChar@@\@xs@StrChar@} +\newcommand\@xs@StrChar@@[2]{% + \edef\@StrMid@First{\@xs@expand#2}\edef\@StrMid@Last{\@xs@expand#2}% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrMid{\xsarg@a}}{}}% + \@call} +\newcommand\@xs@StrChar@[2]{% + \edef\@StrMid@First{\@xs@expand#2}\edef\@StrMid@Last{\@xs@expand#2}% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrMid{#1}}{}}% + \@call}% + +\newcount\Occurrence@StrCount +% Combien de fois compte t-on #2 dans #1 ? +\newcommand\StrCount{\@ifstar\@xs@StrCount@@\@xs@StrCount@} +\newcommand\@xs@StrCount@@[2]{% + \@xs@expand@and@detokenize{\xsarg@a}{#1}% + \@xs@expand@and@detokenize{\xsarg@b}{#2}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrCount{\xsarg@a}{\xsarg@b}}{}}% + \@call} +\newcommand\@xs@StrCount@[2]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrCount{#1}{#2}}{}}% + \@call} +\def\@xs@StrCount#1#2[#3]{% + \Occurrence@StrCount\z@% on initialise à 0 + \def\@xs@StrCount@i{% + \advance\Occurrence@StrCount\@ne% occurrence := occurrence +1 + \@xs@StrPosition[\the\Occurrence@StrCount]{#1}{#2}[\@xs@Pos@StrCount]% position de l'occurrence ? + \ifnum\@xs@Pos@StrCount=\z@% si l'occurrence n'est pas trouvée + \advance\Occurrence@StrCount\m@ne% on enlève 1 au compteur + \@xs@ReturnResult{\the\Occurrence@StrCount}{#3}% et on renvoie ce résultat + \else + \@xs@StrCount@i% si l'occurrence est trouvée, on recommence + \fi}% + \@xs@StrCount@i} + +\newcount\Position@StrPosition +% renvoie la position de l'occurrence #1 de la sous chaine #3 dans la chaine #2 +\newcommand\StrPosition{\@ifstar\@xs@StrPosition@@\@xs@StrPosition@} +\newcommand\@xs@StrPosition@@[3][1]{% + \@xs@expand@and@detokenize{\xsarg@a}{#2}% + \@xs@expand@and@detokenize{\xsarg@b}{#3}% + \edef\@call{\noexpand\@testopt{\noexpand\@xs@StrPosition[\@xs@expand#1]{\xsarg@a}{\xsarg@b}}{}}% + \@call} +\newcommand\@xs@StrPosition@[3][1]{% + \@xs@def\@call{\@xs@expand\@testopt{\@xs@expand\@xs@StrPosition[#1]{#2}{#3}}{}}% + \@call} +\def\@xs@StrPosition[#1]#2#3[#4]{% + \Position@StrPosition\z@ + \ifx\@empty#3\@empty% + \else + \@xs@StrBefore[#1]{#2}{#3}[\@xs@result@StrPosition]% on extrait la chaine avant l'occurrence de #3 + \expandafter\@xs@StrLen\expandafter{\@xs@result@StrPosition}[\@xs@len@StrPosition]% + \Position@StrPosition\@xs@len@StrPosition% + \advance\Position@StrPosition\@ne% \@xs@len@StrPosition+1 est le résultat à priori... + \ifnum\@xs@len@StrPosition=\z@% ... mais si la position vaut 0, soit #3 est au début de #2, soit #3 n'est pas trouvé. On lève le doute ci dessous + \Position@StrPosition\z@% on considère que l'occurrence de #3 n'est pas trouvée, mais... + \ifnum#1=\@ne% si on teste la 1ère occurrence + \@xs@IfBeginWith{#2}{#3}% et que le #2 commence par #3, + {\Position@StrPosition\@ne}% c'est le seul cas où on renvoie 1 + {}% + \fi + \fi + \fi + \expandafter\@xs@ReturnResult\expandafter{\the\Position@StrPosition}{#4}} + +% Définit le délimiteur verb et le développement des arguments par défaut +\AtBeginDocument{\setverbdelim{|}\fullexpandarg} +\endinput +% +% Historique : +% +% 5/7/2008 : premiere sortie de ce package \ No newline at end of file diff --git a/templates/f-tex/zwischensumme.sty b/templates/f-tex/zwischensumme.sty new file mode 100644 index 000000000..043d94fbd --- /dev/null +++ b/templates/f-tex/zwischensumme.sty @@ -0,0 +1,228 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Makros zur Berechnung und Ausgabe einer Zwischensumme bei langen Tabellen +% Der Hack der longtable Ausgabe ist von Heiko Oberdiek, das Paket zref auch. +% ---<(kaimartin)>---(August, 2007) +% +% - Dezimaltrennzeichenn nur noch "." by scripts_at_gpl.coulmann.de 2010-12 +% (raw_numbers patch) +% - \Wert -> default Wert 0, by scripts_at_gpl.coulmann.de 2009-08 +% wenn kein Wert uebergebenn wird, dies +% ermoeglicht das Ausgeben von Tabellen ohne +% Preise (z.b. Lieferscheine) +% - keine Ausgabe der Zwischensumme, wenn 0 +% - neu: \brutto zur Ausgabe von Bruttopreisen by scripts_at_gpl.coulmann.de 2009-07 +% - Anpassungen fuer fancy LaTeX by scripts_at_gpl.coulmann.de 2009-03 +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Diese Datei steht unter der GPL-Lizenz, Version 3 +% siehe http://www.gnu.de/licenses/gpl-3.0.html +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage{etex} % Damit Marken verwendet werden koennen +\usepackage[savepos,user]{zref} % Um die jeweils aktuelle Position zu merken +\usepackage{fltpoint} % Rechnen mit Komma-Zahlen +\usepackage{numprint} % Zahlen formatiert ausgeben +\usepackage{eurosym} % Das Euro-Zeichen +\usepackage{calc} % Fuer das Makro \widthof{} + +% Vorlagen sind auf raw_num Patch ausgelegt daher nur noch . als Trennzeichen +\newcommand{\DecimalSign}{.} +\fpDecimalSign{\DecimalSign} + +% Globale Einstellungen fuer numprint +\npstylegerman % Deutsche Zahlenformatierung, in der Ausgabe +\nprounddigits{2} % Zwei Nachkommasstellen + +% \leer ist bereits in letter.tex definiert, wenn nicht muss es hier passieren +% \newcommand{\leer}{} + +%%%%%%%%%%%%%%Befehle zur Berechnung der Zwischensumme%%%%%%%%%%%%%%%%%%%%%%% +\newcommand*\laufsumme{0} +\newcommand*\resetlaufsumme{\global\def\laufsumme{0}} +\newcommand*\addlaufsumme[1]{\fpAdd{\laufsumme}{\laufsumme}{#1}% + \global\let\laufsumme\laufsumme} +\newcommand*\printwert[1]{ + \ifthenelse{\NoValue > 0}{ + }{ + \numprint{#1} + } +} + + +%%%%%%%%Plaintex-Hack fuer Positionierung der Zwischensummen%%%%%%%%%%%%%%%%%% + + +\makeatletter % Das at-Zeichen in Variablen zulassen + +% Variablen bereit stellen + \newdimen\drx + \newdimen\dry + + \newmarks\ltm@marks + \def\ltm@setmarks#1{% + \marks\ltm@marks{#1}% + } + \def\ltm@getmarks{% + \botmarks\ltm@marks + } + + +% Den aktuellen Wert der Laufsumme berechnen und merken +\newcommand*{\Wert}[1]{% + \ifthenelse{\equal{#1}{\leer}}{ + \addlaufsumme{0}% Den uebergebenen Wert zur Laufsumme addieren + \expandafter\ltm@setmarks\expandafter{\laufsumme}% Die Laufsumme merken + }{ + \printwert{#1}% Ausgabe des Werts vor Ort + \addlaufsumme{#1}% Den uebergebenen Wert zur Laufsumme addieren + \expandafter\ltm@setmarks\expandafter{\laufsumme}% Die Laufsumme merken + } +} + +% Merken der aktuellen Position +\newcommand*{\MarkZwsumPos}{% + \leavevmode + \zsavepos{zwsumpos\thepage}% + \zrefused{zwsumpos\thepage}% +} + + +% Ausgabe der Zwischensumme +\def\ltm@insertfoot#1{% + \vbox to\z@{% + \vss + \hb@xt@\z@{% + \color@begingroup + \zsavepos{tabende\thepage}% % Die aktuelle Position merken + \drx=0sp + \dry=0sp + % Die aktuelle Position abziehen und die gemerkte addieren + \advance \drx by -\zposx{tabende\thepage}sp + \advance \drx by \zposx{zwsumpos\thepage}sp + \advance \dry by -\zposy{tabende\thepage}sp + \advance \dry by \zposy{zwsumpos\thepage}sp + \smash{\kern\drx\raise\dry% + %\hbox{\makebox[\widthof{ \currency}][r]{\printwert{#1} \currency}}% % mit Waehrungszeichen + \hbox{\printwert{#1} }% % ohne Waehrungszeichen + }% end smash + \color@endgroup + }% + }% + \vspace{4mm} +} + +% Ausgabe des Uebertrags +% Wie die Ausgabe der Zwischensumme, nur ohne neu gemerkte Position +\def\ltm@inserthead#1{% + \vbox to\z@{% + \vss + \hb@xt@\z@{% + \color@begingroup + \drx=0sp + \dry=0sp + % Die Position des Tabellenendes abziehen und zur gemerkten gehen + \advance \drx by -\zposx{tabende\thepage}sp + \advance \drx by \zposx{zwsumpos\thepage}sp + \advance \dry by -\zposy{tabende\thepage}sp + \advance \dry by \zposy{zwsumpos\thepage}sp + \smash{\kern\drx\raise\dry% + % Die eigentliche Ausgabe. + % Rechtsbuendig und um die Breite der Währung verschoben. + %\hbox{\makebox[\widthof{ \currency}][r]{\printwert{#1} \currency}}% + \hbox{\printwert{#1}}% % ohne Waehrungszeichen + %\hbox{\makebox[\widthof{ \printwert{#1}}][r]{\printwert{#1}\rule{0mm}{10mm} }}% % ohne Waehrungszeichen + }% end smash + \color@endgroup + }% + }% + \vspace{1mm} +} + + +\def\ltm@lastfoot{\ltm@insertfoot\ltm@getmarks} +\def\ltm@foot{\ltm@insertfoot{\ltm@getmarks}} +\def\ltm@head{\ltm@inserthead{\ltm@getmarks}} + + +% Ueberschreiben der Output-Routine von longtable +\def\LT@output{% + \ifnum\outputpenalty <-\@Mi + \ifnum\outputpenalty > -\LT@end@pen + \LT@err{floats and marginpars % + not allowed in a longtable}\@ehc + \else + \setbox\z@\vbox{\unvbox\@cclv}% + \ifdim \ht\LT@lastfoot>\ht\LT@foot + \dimen@\pagegoal + \advance\dimen@-\ht\LT@lastfoot + \ifdim\dimen@<\ht\z@ + \setbox\@cclv\vbox{% + \unvbox\z@\copy\LT@foot\ltm@foot\vss + }% + \@makecol + \@outputpage + \setbox\z@\vbox{\box\LT@head}% + \fi + \fi + \global\@colroom\@colht + \global\vsize\@colht + \vbox{% + \unvbox\z@ + \box\ifvoid\LT@lastfoot + \LT@foot\ltm@foot + \else + \LT@lastfoot\ltm@lastfoot + \fi + }% + \fi + \else + \setbox\@cclv\vbox{% + \unvbox\@cclv\copy\LT@foot\ltm@foot\vss + }% + \@makecol + \@outputpage + \global\vsize\@colroom + \copy\LT@head\ltm@head + \fi +} + +\newcommand\BruttoSellPrice[2]{ + \fpAdd{\tax}{#2}{100} + \fpDiv{\taxF}{\tax}{100} + \fpMul{\result}{#1}{\taxF} + \numprint{\result} +} +\newcommand\BruttoWert[2]{ + \fpAdd{\tax}{#2}{100} + \fpDiv{\taxF}{\tax}{100} + \fpMul{\rawresult}{#1}{\taxF} + \Wert{\rawresult} +} + + +\newcommand\BruttoLineSum[4]{ + \fpAdd{\tax}{#4}{100} + \fpDiv{\taxF}{\tax}{100} + \fpMul{\result}{#1}{\taxF} + \fpMul{\result}{#2}{\result} + \fpSub{\rabatt}{100}{#3} + \fpDiv{\rabatt}{\rabatt}{100} + \fpMul{\result}{\result}{\rabatt} + \Wert{\result} +} + +% \ifthenelse{\equal{<%p_discount%>}{0}}{}{ -<%p_discount%>\%} & +% %<%sellprice%> +% \Wert{<%linetotal%>} % Zeilensumme + +% \fpMul{\result}{#1}{1.19} +% \fpMul{\resultt}{#2}{\result} +% \fpSub{\rabatt}{100}{#3} +% \fpDiv{\rabattt}{\rabatt}{100} +% \fpMul{\resulttt}{\resultt}{\rabattt} +% %\fpRound{\roundresult}{\result}{3} +% %\roundresult +% \resulttt + +\makeatother % Das at-Zeichen in Variablen wieder verbieten +%%%%%%%%%%%%%%%%%%%%Ende plaintex-Hack%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- 2.20.1