Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an import mechanism #1284

Open
tobiasBora opened this issue Oct 3, 2023 · 5 comments
Open

Add an import mechanism #1284

tobiasBora opened this issue Oct 3, 2023 · 5 comments

Comments

@tobiasBora
Copy link

tobiasBora commented Oct 3, 2023

Brief outline of the proposed feature

I often find myself creating nested styles like:

\pgfkeys{
  /mystyle/.style={
    set fill/.style={fill=##1, opacity=.5},
  }
}

While it works nicely, it can quickly become a mess: for instance, to edit later set fill, I need to do something like /mystyle/.append style={set fill/.style={new def}}, and it can quickly be hard to read and not super robust. Moreover, this makes it hard to to call a single style (e.g. how do I load the style set fill without loading all styles in mystyle?) I’m also even more worried by efficiency: in practice, I call mystyle in every single node that I am drawing and it can be quite time consuming.

I know it is possible to do .search also={/conf my style}, but then I need to start every single style with /tikz/.cd, and, more importantly, this solution assumes that I run this into tikz, but in practice it might not be the case. For instance, I might call it inside a tikzcd matrix that starts with somtething like /tikzcd/commutative diagram/.cd: so if I do /tikz/.cd I am unable to see stuff defined in /tikzcd/commutative diagram… and I also get some breakages that I cannot explain.

It would be much more handy to have a .import={/conf mystyle} that takes all keys defined in /conf mystyle and just "insert" them here, basically like if I did a copy paste of all keys in /conf mystyle/.

Usage example

Try to uncomment the line /some other libraries/.cd,, and you will see the issue. On the other hand, \myNodeInneficient has this line uncommented and it works… but I need to copy/paste the whole definition and/or use nested styles, which I don't like.

\documentclass[options]{article}

\usepackage{tikz}
\usepackage{etoolbox}

\begin{document}

\makeatletter
\pgfkeys{
  /test/.cd,
  every node/.style={},
  nodes/.code={%
    \scantokens{%
      \pgfkeysalso{%
        /test/every node/.append style={#1}%
      }%
    }%
  },%
  /conf test/.cd,
  %% Here I put many helper functions
  my opacity/.style={
    /tikz/.cd,%%% <--- I don't want this: what if I call it outside of tikz?
    opacity=#1,
  },
  set semi fill/.style={
    /tikz/.cd,%%% <--- I don't want this: what if I call it outside of tikz?
    set fill=#1,
    my opacity=.5
  },
}

\pgfkeys{
  /test/nodes={
    set fill/.style={fill=#1},
    set fill=green,
  },
}

\pgfkeys{
  /some other libraries/.cd,
  .search also={/tikz},
}


\NewDocumentCommand{\myNode}{O{}m}{
  \node[
    %% Try to uncomment this: it will all break, while this should technically also search in /tikz
    %/some other libraries/.cd,
    draw, .search also={/conf test}, /test/every node,
  #1]{#2};
}


%% This is like \myNode, but I copy/pasted the keys in /conf test instead of using .search also
\NewDocumentCommand{\myNodeInneficient}{O{}m}{
  \node[
    %% See: here I can uncomment this line
    /some other libraries/.cd,
    draw,
    %% Here I put many helper functions
    my opacity/.style={
      opacity=#1,
    },
    set semi fill/.style={
      set fill=#1,
      my opacity=.5
    },
    /test/every node,
  #1]{#2};
}

\makeatother

\begin{tikzpicture}
  \myNode[
  %set semi fill=red
  ]{Hey}
  \myNodeInneficient[xshift=2cm]{Not efficient}
\end{tikzpicture}

\end{document}
@hmenke
Copy link
Member

hmenke commented Oct 5, 2023

.search also is not additive. It overrides any previously present .unknown handler. You need to explicitly list all the namespaces you want to have searched.

@@ -45,8 +45,8 @@
 \NewDocumentCommand{\myNode}{O{}m}{
   \node[
     %% Try to uncomment this: it will all break, while this should technically also search in /tikz
-    %/some other libraries/.cd,
-    draw, .search also={/conf test}, /test/every node,
+    /some other libraries/.cd,
+    draw, .search also={/conf test,/tikz}, /test/every node,
   #1]{#2};
 }

@tobiasBora
Copy link
Author

tobiasBora commented Oct 5, 2023

Thanks, but wouldn’t it be possible to create an additive version of .search also? (actually, if it is not additive, shouldn’t it be named .search instead?) It might be hard (or impossible if the user also import some styles?) to track all paths that have been previously configured.

Ideally, this version could also allow the import individual styles, like:

\pgfkeys{
  /my styles/.cd,
  style A/.style={fill=red},
  style B/.style={fill=green},
  style C/.style={fill=red},

  /group style/.cd,
  style D/.style={fill=red},
  style E/.style={fill=green},
  style F/.style={fill=red},
}
% …
\node[
  .import={/group style, /my styles/style A, /my styles/style B},
  % here I should be able to call "style {A,B,D,E,F}", but not "style C"
  style A,
]{};

@muzimuzhi
Copy link
Member

A <key>/.import={<full path list>} handler calls for keeping track of all known keys in a tree structure. Only then it's possible to implement something like

# expressed as python import statements
# https://docs.python.org/3/reference/simple_stmts.html#the-import-statement
from group_style import *
from my_styles import style_A, style_B

An additive <key>/.search also needs to determine if the corresponding <full path>/.unknown/.@cmd is already set by previous use(s) of .search also.

Maybe both can start with third-party pgfkeys libraries.

@hmenke
Copy link
Member

hmenke commented Oct 6, 2023

Isn't this what pgfkeysfiltered is supposed to do?

@tobiasBora
Copy link
Author

@hmenke pgfkeysfiltered seems to solve another question I was having, but I don't see how it helps here (at least to solve the initial problem, it might help to do partial import, but since we do not have complete input yet it is maybe a bit early): the doc says that it does exactly like \pgfkeys except that it might decide not to evaluate some keys… but the problem is that the /.cd already removes some keys, so we want to add keys, not remove even more keys. Am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants