1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2    Copyright (c) 2012-2021 The plumed team
3    (see the PEOPLE file at the root of the distribution for a list of names)
4 
5    See http://www.plumed.org for more information.
6 
7    This file is part of plumed, version 2.
8 
9    plumed is free software: you can redistribute it and/or modify
10    it under the terms of the GNU Lesser General Public License as published by
11    the Free Software Foundation, either version 3 of the License, or
12    (at your option) any later version.
13 
14    plumed is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public License
20    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #ifndef __PLUMED_tools_Keywords_h
23 #define __PLUMED_tools_Keywords_h
24 #include <vector>
25 #include <string>
26 #include <set>
27 #include <map>
28 
29 #include "Exception.h"
30 
31 namespace PLMD {
32 
33 class Log;
34 
35 /// This class holds the keywords and their documentation
36 class Keywords {
37 /// This class lets me pass keyword types easily
38   class KeyType {
39   public:
40     enum {hidden,compulsory,flag,optional,atoms,vessel} style;
41     explicit KeyType( const std::string& type );
42     void setStyle( const std::string& type );
isCompulsory()43     bool isCompulsory() const { return (style==compulsory); }
isFlag()44     bool isFlag() const { return (style==flag); }
isOptional()45     bool isOptional() const { return (style==optional); }
isAtomList()46     bool isAtomList() const { return (style==atoms); }
isVessel()47     bool isVessel() const { return (style==vessel); }
toString()48     std::string toString() const {
49       if(style==compulsory) return "compulsory";
50       else if(style==optional) return "optional";
51       else if(style==atoms) return "atoms";
52       else if(style==flag) return "flag";
53       else if(style==hidden) return "hidden";
54       else if(style==vessel) return "vessel";
55       else plumed_assert(0);
56       return "";
57     }
58   };
59   friend class Action;
60 private:
61 /// Is this an action or driver (this bool affects what style==atoms does in print)
62   bool isaction;
63 /// This allows us to overwrite the behavior of the atoms type in analysis actions
64   bool isatoms;
65 /// The names of the allowed keywords
66   std::vector<std::string> keys;
67 /// The names of the reserved keywords
68   std::vector<std::string> reserved_keys;
69 /// Whether the keyword is compulsory, optional...
70   std::map<std::string,KeyType> types;
71 /// Do we allow stuff like key1, key2 etc
72   std::map<std::string,bool> allowmultiple;
73 /// The documentation for the keywords
74   std::map<std::string,std::string> documentation;
75 /// The default values for the flags (are they on or of)
76   std::map<std::string,bool> booldefs;
77 /// The default values (if there are default values) for compulsory keywords
78   std::map<std::string,std::string> numdefs;
79 /// The tags for atoms - we use this so the manual can differentiate between different ways of specifying atoms
80   std::map<std::string,std::string> atomtags;
81 /// The string that should be printed out to describe how the components work for this particular action
82   std::string cstring;
83 /// The names of all the possible components for an action
84   std::vector<std::string> cnames;
85 /// The keyword that turns on a particular component
86   std::map<std::string,std::string> ckey;
87 /// The documentation for a particular component
88   std::map<std::string,std::string> cdocs;
89 /// Print the documentation for the jth keyword in html
90   void print_html_item( const std::string& ) const;
91 /// Print a particular keyword
92   void printKeyword( const std::string& j, Log& log ) const ;
93 /// Print a particular keyword (copy of the above that works with files)
94   void printKeyword( const std::string& j, FILE* out ) const ;
95 public:
96 /// Constructor
Keywords()97   Keywords() : isaction(true), isatoms(true) {}
98 ///
isDriver()99   void isDriver() { isaction=false; }
100 ///
isAnalysis()101   void isAnalysis() { isatoms=false; }
102 /// find out whether flag key is on or off by default.
103   bool getLogicalDefault( std::string key, bool& def ) const ;
104 /// Get the value of the default for the keyword named key
105   bool getDefaultValue( std::string key, std::string& def ) const ;
106 /// Return the number of defined keywords
107   unsigned size() const;
108 /// Check if numbered keywords are allowed for this action
109   bool numbered( const std::string & k ) const ;
110 /// Return the ith keyword
111   std::string getKeyword( const unsigned i ) const ;
112 /// Print the documentation to the log file (used by PLMD::Action::error)
113   void print( Log& log ) const ;
114 /// Print the documentation to a file (use by PLUMED::CLTool::readCommandLineArgs)
115   void print( FILE* out ) const ;
116 /// Print a file containing the list of keywords for a particular action (used for spell checking)
117   void print_spelling() const ;
118 /// Reserve a keyword
119   void reserve( const std::string & t, const std::string & k, const std::string & d );
120 /// Reserve a flag
121   void reserveFlag( const std::string & k, const bool def, const std::string & d );
122 /// Use one of the reserved keywords
123   void use( const std::string  & k );
124 /// Get the ith keyword
125   std::string get( const unsigned k ) const ;
126 /// Add a new keyword of type t with name k and description d
127   void add( const std::string & t, const std::string & k, const std::string & d );
128 /// Add a new compulsory keyword (t must equal compulsory) with name k, default value def and description d
129   void add( const std::string & t, const std::string & k, const std::string & def, const std::string & d );
130 /// Add a falg with name k that is by default on if def is true and off if def is false.  d should provide a description of the flag
131   void addFlag( const std::string & k, const bool def, const std::string & d );
132 /// Remove the keyword with name k
133   void remove( const std::string & k );
134 /// Check if there is a keyword with name k
135   bool exists( const std::string & k ) const ;
136 /// Check the keyword k has been reserved
137   bool reserved( const std::string & k ) const ;
138 /// Check if the keyword with name k has style t
139   bool style( const std::string & k, const std::string & t ) const ;
140 /// Print an html version of the documentation
141   void print_html() const ;
142 /// Print keywords in form readable by vim
143   void print_vim() const ;
144 /// Print the template version for the documentation
145   void print_template( const std::string& actionname, bool include_optional) const ;
146 /// Change the style of a keyword
147   void reset_style( const std::string & k, const std::string & style );
148 /// Add keywords from one keyword object to another
149   void add( const Keywords& keys );
150 /// Copy the keywords data
151   void copyData( std::vector<std::string>& kk, std::vector<std::string>& rk, std::map<std::string,KeyType>& tt, std::map<std::string,bool>& am,
152                  std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
153                  std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
154                  std::map<std::string,std::string>& cd ) const ;
155 /// Clear everything from the keywords object.
156 /// Not actually needed if your Keywords object is going out of scope.
157   void destroyData();
158 /// Set the text that introduces how the components for this action are introduced
159   void setComponentsIntroduction( const std::string& instr );
160 /// Add a potential component which can be output by this particular action
161   void addOutputComponent( const std::string& name, const std::string& key, const std::string& descr );
162 /// Has a component with this name been added?
163   bool outputComponentExists( const std::string& name, const bool& custom ) const ;
164 /// Get the description of this component
165   std::string getOutputComponentDescription( const std::string& name ) const ;
166 /// Remove a component with a particular name from the keywords
167   void removeComponent( const std::string& name );
168 /// Reference to keys
getKeys()169   std::vector<std::string> getKeys() const { return keys; }
170 /// Get the description of a particular keyword
171   std::string getTooltip( const std::string& name ) const ;
172 };
173 
174 }
175 
176 #endif
177