goLaTeX - Mein LaTeX-Forum

Mein LaTeX-Forum


Login  | Registrieren
Direktlinks:
Zuletzt aktive Beiträge
Unbeantwortete Beiträge
[Erweitert]

Forenstatistik:
Beiträge: 98899
Top-Poster: Johannes_B (5059)

Wir begrüßen unseren neuesten Benutzer tobi_nambur.

Links:


Mit Unterstützung von DANTE e.V.: Deutschsprachige Anwendervereinigung TeX. Danke den Mitgliedern!





Forum
      Option
[Erweitert]
  • Diese Seite weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

\ifstrequal funktioniert nicht mit pgfkeys

 

Achim123
Forum-Newbie
Forum-Newbie

Beiträge: 4
Anmeldedatum: 31.01.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 31.01.2019, 19:35     Titel: \ifstrequal funktioniert nicht mit pgfkeys
  Antworten mit Zitat      
Hallo,

ich habe ein Problem und konnte es leider trotz einiger Lektüre nicht lösen. Ich möchte gerne Variablen in einer Style-Datei verwalten können. Im tatsächlichen LaTeX-File möchte ich die Variable ändern können, und je nach Wert der Variable, z.B. true oder false, soll mir ein Getter, z.B. \getvalue, etwas anderes zurückgeben.

Ich habe da mal ein Minimalbeispiel vorbereitet, das sich mit Lualatex (TeX Live 2016/Debian) kompilieren lassen sollte:

Code • Öffne in Overleaf
\documentclass{report}

\usepackage{pgfkeys}
\RequirePackage{pgfopts}
\RequirePackage{xcolor}
\RequirePackage{parselines}
\RequirePackage{filecontents}
\usepackage{etoolbox}

%%%%%%%%%%%%%%%%%%%%%
%%      GETTER UND SETTER
\newcommand{\setvalue}[1]{\pgfkeys{/variables/#1}}
\newcommand{\getvalue}[1]{%
        \ifstrequal{\pgfkeysvalueof{/variables/#1}}{true}{%
                true}{false%
        }

        In der Variable steht aber:
        \pgfkeysvalueof{/variables/#1}
}
\newcommand{\declare}[1]{%
\pgfkeys{
        /variables/#1.is family,
        /variables/#1.unknown/.style = {\pgfkeyscurrentpath/\pgfkeyscurrentname/.initial = ##1
}
        }%
}

\declare{}


%%%%%%%%%%%%%%%%%
%% BEGIN DOCUMENT
\begin{document}
\setvalue{VARIABLE1 = true}

Die Auswertung ergibt:
\getvalue{VARIABLE1} % schreibt immer "false"

\declare{test/}

\end{document}


Meine Vermutung ist ja, dass es was mit expandafter zu tun hat, aber ... hm ... bin einfach noch nicht dahinter gestiegen, was es sein könnte :-/

Habt ihr eine Idee?
Private Nachricht senden Benutzer-Profile anzeigen

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 31.01.2019, 20:03     Titel:
  Antworten mit Zitat      
Nun, \ifstrequal expandiert laut Anleitung die Argumente, die es vergleicht nicht, sondern vergleicht direkt die Zeichenkette. Und dass eine Zeichenkette, die \pgfkeysvalueof] enthält niemals mit der Zeichenkette true identisch sein kann, sollte nicht soooo wahnsinnig verwunden. Du kannst aber stattdessen erst einmal ein Makro mit \pgfkeysgetvalue definieren und dann mit Hilfe von \ifcsstring mit true vergleichen:
Code • Öffne in Overleaf
\documentclass{report}

\usepackage{pgfkeys}
\RequirePackage{pgfopts}
\RequirePackage{xcolor}
\RequirePackage{parselines}
\RequirePackage{filecontents}
\usepackage{etoolbox}

%%%%%%%%%%%%%%%%%%%%%
%%      GETTER UND SETTER
\newcommand*{\tempvar}{}% Fehlermeldung, falls schon jemand \tempvar verwendet.
\newcommand{\setvalue}[1]{\pgfkeys{/variables/#1}}
\newcommand{\getvalue}[1]{%
  \pgfkeysgetvalue{/variables/#1}{\tempvar}
  \ifcsstring{tempvar}{true}{%
                true}{false%
        }

        In der Variable steht:
        \pgfkeysvalueof{/variables/#1}
}
\newcommand{\declare}[1]{%
\pgfkeys{
        /variables/#1.is family,
        /variables/#1.unknown/.style = {\pgfkeyscurrentpath/\pgfkeyscurrentname/.initial = ##1
}
        }%
}

\declare{}


%%%%%%%%%%%%%%%%%
%% BEGIN DOCUMENT
\begin{document}
\setvalue{VARIABLE1 = true}

Die Auswertung ergibt:
\getvalue{VARIABLE1} % schreibt immer "false"

\declare{test/}

\end{document}

Wobei mir der Sinn von \getvalue nicht wirklich klar ist. Daher sei noch darauf hingewiesen, dass pgfkeys für boolsche Variablen spezielle Routinen bereitstellt.

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 31.01.2019, 20:10     Titel:
  Antworten mit Zitat      
Das ist in der Tat eine Expansions-Frage. \ifstrequal geht davon aus, dass es zwei Strings als Argument bekommt. In dem Fall hier bekommt es aber ein Argument, das nach drei Expansionsschritten ein String wird (wenn ich richtig gezählt habe) und einen String. Du müsstest \pgfkeysvalueof{/variables/#1} drei mal expandieren, um an den String zu kommen. Das braucht dann zwei mal sieben \expandafters. Stattdessen kannst Du aber auch mit einer Hilfsvariable und \edef/\expandthrice arbeiten.

Code • Öffne in Overleaf
\documentclass{article}

\usepackage{pgfkeys}
\RequirePackage{pgfopts}
\usepackage{etoolbox}

% wie \expandonce von etoolbox, nur dreimal
\newcommand\expandthrice{%
  \unexpanded\expandafter\expandafter\expandafter
  \expandafter\expandafter\expandafter\expandafter}

\newcommand{\setvalue}[1]{\pgfkeys{/variables/#1}}
\newcommand{\getvalue}[1]{%
  \expandafter\expandafter\expandafter\expandafter\expandafter
  \expandafter\expandafter
  \ifstrequal
  \expandafter\expandafter\expandafter\expandafter\expandafter
  \expandafter\expandafter
  {\pgfkeysvalueof{/variables/#1}}{true}
    {true}
    {false}%

  \edef\getvaltmp{\expandthrice{\pgfkeysvalueof{/variables/#1}}}%
  \ifdefstring{\getvaltmp}{true}
    {true}
    {false}%

  In der Variable steht aber:
  \pgfkeysvalueof{/variables/#1}
}
\newcommand{\declare}[1]{%
  \pgfkeys{
    /variables/#1.is family,
    /variables/#1.unknown/.style = {\pgfkeyscurrentpath/\pgfkeyscurrentname/.initial = ##1
}
  }%
}

\declare{}


\begin{document
}
\setvalue{VARIABLE1 = true}

Die Auswertung ergibt:
\getvalue{VARIABLE1}

\declare{test/}
\end{document}


Je nach echter Anwedung gibt es da vielleicht deutlich bessere Methoden. Und vielleicht kann auch pgfkeys selbst noch was Besseres (da bin ich aber überfragt).

Achim123
Forum-Newbie
Forum-Newbie

Beiträge: 4
Anmeldedatum: 31.01.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.02.2019, 09:43     Titel:
  Antworten mit Zitat      
Was ... um alles in der Welt ... *sieben* \expandafter, zweimal?

Ok, mega krass ... wie bist du da drauf gekommen, dass das so gehen könnte? (noch nicht getestet) Ich möchte ja für die Zukunft lernen und nächstes Mal selbst draufkommen oder es selbst recherchieren können

Vielen Dank schonmal!
Private Nachricht senden Benutzer-Profile anzeigen

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.02.2019, 10:47     Titel:
  Antworten mit Zitat      
So etwas braucht entweder intime Kenntnisse über die Definition oder Ausprobieren.

Ich würde aber stattdessen empfehlen, auf derartige interne Kenntnisse zu verzichten. Solche Hackerlösungen gehen schon einmal kaputt, was üblicherweise bei der Verwendung dafür vorgesehener Schnittstellen eines Pakets nicht passiert (oder dann ggf. als Bug gemeldet werden kann).

Achim123
Forum-Newbie
Forum-Newbie

Beiträge: 4
Anmeldedatum: 31.01.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.02.2019, 11:08     Titel:
  Antworten mit Zitat      
Hm, ok. Gibt es denn eine andere Möglichkeit, eine Variable auf Gleichheit mit einem String zu testen als \ifstrequal ? Wie machen andere das in LaTeX, wenn sie wissen wollen, was in einer Variablen drinsteht?
Private Nachricht senden Benutzer-Profile anzeigen

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.02.2019, 12:04     Titel:
  Antworten mit Zitat      
Wurde doch oben gezeigt und auch in meinem letzten Kommentar gleich zweimal verlinkt. Nur weil zwei Gäste zwei unterschiedliche Antworten gegeben haben, ist das doch kein Grund die erste komplett zu ignorieren …

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.02.2019, 12:06     Titel:
  Antworten mit Zitat      
Das kommt ganz auf die Aufgabenstellung an. Wenn ich nur wissen will, was in einer Variablen drin steht, kann ich sie mir ja einfach ausgeben lassen. Für die interne Verwendung in Paketen gibt es häufig andere Methoden als mit Strings zu arbeiten, sodass man sich die recht komplexen Stringvergleiche sparen kann. Bei Boolean-Werten bin ich zum Beispiel ein Freund von toggles aus etoolbox, aber es gibt viele ähnliche und andere Methoden. Wenn es um die Ausgabe von irgendwas geht, dann ist es häufig einfacher, die Ausgabe von Anfang an so auszulegen, dass man den String einfach ausgibt, anstatt ihn noch aufwendig testen zu müssen und dann zu reagieren.

Die um 19:03 gezeigte Lösung nutzt statt des Expandierballets mit \edef oder \expandafter eben direkt eine Schnittstelle von pgfkeys und ist daher nicht nur einfacher zu verstehen sondern, wie erwähnt, auch sicherer. (Gibt es einen Grund, warum Du \ifcsstring verwendet hast? Ich hätte hier \ifdefstring{\tempvar}{true} wegen der Verwendung von \tempvar in \pgfkeysgetvalue{/variables/#1}{\tempvar} fast klarer gefunden.)

Den ganzen Lösungen hier liegt aber zugrunde, dass man zwischen einer Variablen (einem Makro) und ihrem Wert (seiner Expansion) unterscheiden muss.

Achim123
Forum-Newbie
Forum-Newbie

Beiträge: 4
Anmeldedatum: 31.01.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.02.2019, 14:35     Titel:
  Antworten mit Zitat      
Oh, ok, ja, ich hatte die erste Lösung überlesen Sad Sorry!

Vielen lieben Dank. Ich glaube, ich komme damit erstmal weiter. Habe auch \ifcsstring verwendet und mit \edef\tempvar{} direkt in \getvalue geschrieben. Scheint mir aufgeräumter(?)
Private Nachricht senden Benutzer-Profile anzeigen

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.02.2019, 15:36     Titel:
  Antworten mit Zitat      
Mhhh, ich dachte wir waren uns alle einig, dass
Code • Öffne in Overleaf
\pgfkeysgetvalue{/variables/#1}{\tempvar}
die bessere Variante war? \edef\getvaltmp{\expandthrice{\pgfkeysvalueof{/variables/#1}}}% geht zwar auch, ist aber von der Implementation abhängig und nutzt eben nicht die extra bereitgestellten Schnittstellen. Daher schrieb ich ja auch: "Je nach echter Anwendung gibt es da vielleicht deutlich bessere Methoden. Und vielleicht kann auch pgfkeys selbst noch was Besseres (da bin ich aber überfragt)." (Das Timing war natürlich etwas unglücklich. Als ich meine Antwort schrieb, war die von 19:03 noch nicht da. Aber da ich so lange getippt habe, war sie später fertig als die Antwort von 19:03, die ja eine passende Schnittstelle demonstriert.)

Mit der \pgfkeysgetvalue-Methode ist, soweit ich sehen kann, gar kein \edef erforderlich (und das ist auch gut, denn \edefs können manchmal unerwartete Effekte haben, wenn man nicht genau aufpasst).

Neues Thema eröffnen Neue Antwort erstellen



Options and Permissions
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum herunterladen
.

goLaTeX ist Teil der goForen
goForen.de goMATLAB.de goLaTeX.de


  Datenschutzerklärung | Impressum | FAQ | goLaTeX RSS Button RSS-Feed

Copyright © 2008 - 2019 goLaTeX.de