-
Notifications
You must be signed in to change notification settings - Fork 15
Added parametrized chunks #147
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
base: master
Are you sure you want to change the base?
Conversation
doc/Comments.xml
Outdated
| That chunk of text can then later on be inserted in any other place by using the | ||
| @InsertChunk <A>name</A> command. | ||
|
|
||
| In the text, you can use <A>%param1</A> placeholders, which will then be overwritten |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest to use %param1% instead of %param1, otherwise, it becomes hard to impossible to insert a placeholder not followed by a space.
Alternatively, switch to asymmetric delimiters which then also might be used in future extensions. E.g. use {param1}, and then later one can (if desired) add more complex substitution rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I switched to %{param1}.
doc/Comments.xml
Outdated
| #! @InsertChunk MyChunk world | ||
| ## The text "Hello, world." is inserted right before this. | ||
| ## The text "Hello, Max." is inserted right behind this comment | ||
| #! @InsertChunk MyChunk Max |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change Max to something more universal, e.g. universe or user, or ...
| DeclareOperation( "DocumentationExample", [ IsTreeForDocumentation ] ); | ||
| DeclareOperation( "DocumentationDummy", [ IsTreeForDocumentation, IsString, IsList ] ); | ||
| DeclareOperation( "DocumentationDummy", [ IsTreeForDocumentation, IsString ] ); | ||
| DeclareOperation( "DocumentationDummyInstance", [ IsTreeForDocumentation, IsTreeForDocumentationNode ] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this name DocumentationDummyInstance? I'd never guess that it is related to parametrized chunks. Why not e.g. DocumentationParametrizedChunk?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not related to parametrized chunks. Previously, for a chunk a dummy was created, and the same dummy was inserted into the tree. Now, for a chunk a dummy is created, but each time a chunk is inserted in the tree, a dummy instance is inserted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how you can say it is not related when clearly they are related (one is used to implement the other) :-).
Anyway: I guess I find these names very unfortunate. What's a "dummy" here? I grepped through the code, and the whole "dummy" stuff is only ever used to implement chunks. So why isn't it called "chunk"?
I am also confused as to the relation between "Dummy" and "DummyInstance". While I am pretty hopeful I could figure it out from digging through the code, I feel that (a) better names, and (b) at least some minimal comments, would go a long way to making this code more understandable (and hence maintainable).
What I gathered so far is that before this PR, DocumentationDummy is called both for creating and inserting a "chunk". Now it is only called for creating it, while DocumentationDummyInstance is called for inserting it. So, why not replace those operations with functions MakeChunk and InsertChunk, which do what their names suggest? They could then also perform the extra tests I suggest below (i.e. the former would produce an error if a chunk with that name already exists, while the latter could produce an error if no chunk with that name was declared before).
| title := parameters[ 1 ]; | ||
| elif Length( parameters ) = 2 then | ||
| vars := parameters[ 2 ]; | ||
| vars := SplitString( vars, "," ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add a check like if not ForAll(vars, IsValidIdentifier) then Error(...); fi; to prevent users from doing weird things (like using a param name containing %). While it might not matter much right now, it will make future extensions easier.
Thinking about it, the chunk name should also be restricted this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can restrict the var names to be alphanumeric, probably with _ in it. Will do that.
doc/Comments.xml
Outdated
|
|
||
| In the text, you can use <A>%param1</A> placeholders, which will then be overwritten | ||
| by the <A>param1_value</A> parameters when the text is inserted. Different parameters | ||
| may not contain spaces and must be separated by a comma. Different values may contain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is meant with "Different parameters"? Do you mean the parameter names?
I'd in fact restrict them to valid identifiers, see below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, "Different parameters" sounds weird to me. What are "Equal parameters"? Same for "Different values". The more I think about it, I'd completely rewrite this paragraph. Here is a suggestion:
Chunks may optionally be parametrized, by specifying a comma-separated list of parameter names after the chunk name given to @BeginChunk. Each parameter name must be a valid GAP identifier (and hence may only contain letters, digits and underscores).
When inserting a parametrized chunk, a comma-separated list of parameter values must follow the chunk name given to @InsertChunk. The number of parameter values must match the number of parameter names.
When this is done, instead of directly inserting the chunk text, for every parameter param, every occurrence of the string {param} is substituted by the corresponding parameter value.
doc/Comments.xml
Outdated
| by the <A>param1_value</A> parameters when the text is inserted. Different parameters | ||
| may not contain spaces and must be separated by a comma. Different values may contain | ||
| spaces and must be separated by a comma. There must be a value for each parameter. Please | ||
| note that this is not checked by &AutoDoc;. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided not to do this. I can only check this at the point of writing out the xml, as the insertion might be read before the actual chunk. Then I could not point to the place where it is wrong. I can still provide an error message, but it might not contain all information people want. Will insert it anyway.
0932998 to
b394409
Compare
| ###################################### | ||
|
|
||
| BindGlobal( "AUTODOC_IdentifierLetters", | ||
| "+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So an AutoDoc identifier is allowed to contain minus and plus? Why? What is this used for?
| DeclareOperation( "DocumentationExample", [ IsTreeForDocumentation ] ); | ||
| DeclareOperation( "DocumentationDummy", [ IsTreeForDocumentation, IsString, IsList ] ); | ||
| DeclareOperation( "DocumentationDummy", [ IsTreeForDocumentation, IsString ] ); | ||
| DeclareOperation( "DocumentationDummyInstance", [ IsTreeForDocumentation, IsTreeForDocumentationNode ] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how you can say it is not related when clearly they are related (one is used to implement the other) :-).
Anyway: I guess I find these names very unfortunate. What's a "dummy" here? I grepped through the code, and the whole "dummy" stuff is only ever used to implement chunks. So why isn't it called "chunk"?
I am also confused as to the relation between "Dummy" and "DummyInstance". While I am pretty hopeful I could figure it out from digging through the code, I feel that (a) better names, and (b) at least some minimal comments, would go a long way to making this code more understandable (and hence maintainable).
What I gathered so far is that before this PR, DocumentationDummy is called both for creating and inserting a "chunk". Now it is only called for creating it, while DocumentationDummyInstance is called for inserting it. So, why not replace those operations with functions MakeChunk and InsertChunk, which do what their names suggest? They could then also perform the extra tests I suggest below (i.e. the former would produce an error if a chunk with that name already exists, while the latter could produce an error if no chunk with that name was declared before).
| IsTreeForDocumentationNodeRep, | ||
| [ ] ); | ||
|
|
||
| BindGlobal( "TheTypeOfDocumentationTreeDummyInstanceNodes", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does the type have an extra "Tree" in the name?
| ErrorWithPos( Concatenation( "Wrong chunk parameters: ", current_command[ 2 ] ) ); | ||
| fi; | ||
| if not ForAll( title, i -> i in AUTODOC_IdentifierLetters ) then | ||
| ErrorWithPos( Concatenation( "Wrong character in chunk title: ", title ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That error message is not very helpful. Which character is wrong? And what does that mean? Perhaps "Invalid chunk name TITLE (chunk names must be identifiers)" -- the user can lookup in the manual what an "identifier" is. Or else explicitly say it, e.g., "(chunk names must only contain letters, digits and underscores)"
| fi; | ||
| for current_var in vars do | ||
| if not ForAll( current_var, i -> i in AUTODOC_IdentifierLetters ) then | ||
| ErrorWithPos( Concatenation( "Wrong character in chunk parameter: ", current_var ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar as above.
| vars := parameters{[ position_first_space + 1 .. Length( parameters ) ]}; | ||
| vars := SplitString( vars, "," ); | ||
| else | ||
| ErrorWithPos( Concatenation( "Wrong InsertChunk parameters: ", parameters ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That error text is no very helpful. What is wrong?
| variables := List( variables, i -> Concatenation( "%{", i, "}" ) ); | ||
| variable_values := node!.variable_values; | ||
| if Length( variables ) <> Length( variable_values ) then | ||
| Error( "While inserting chunk ", dummy_label, ": wrong number of parameter values" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error should not ever happen, right? Because of filtering we performed before. So, Perhaps turn this into an Assert?
Although... does the system prevent the user from re-defining a chunk? I.e. from using @BeginChunk twice with the same name, but possibly different numbers of parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried this, and you can do it (undocumented!) -- seems the chunks get concatenated. Is that intentional? I am tempted to forbid it.
Conversely, it is possible to insert a non-existing chunk, which I think will make for hilarious debugging fun. Now it's OK to insert a chunk before it is declared (so you can't check for this in @InsertChunk), but when writing it, we should IMHO detect if there isn't a chunk with that name specified. That would suggest storing for each @InsertChunk the file and line it was used in, so that the delayed error message can correctly pinpoint the problem. Alternatively, demand that chunks are declared before use? (But that's a bit tricky, because we currently do not specify in which order files are read. Which is a problem, too, I guess...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated, but while looking through the code, I saw that there is a 3-arg version of DocumentationDummy which apparently is unused -- delete it?
| ErrorWithPos( Concatenation( "Wrong InsertChunk parameters: ", parameters ) ); | ||
| fi; | ||
| inserted_dummy := DocumentationDummyInstance( tree, DocumentationDummy( tree, title ) ); | ||
| inserted_dummy!.variable_values := vars; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd feel more natural to me pass vars to DocumentationDummyInstance (resp. to InsertChunk in the bigger change I suggest)
|
@sebasguts just to make sure there is no misunderstanding: I am waiting for revisions resp. responses by you, so I am not otherwise thinking about this PR anymore. |
|
@sebasguts this needs to be rebased, and comments be addressed |
|
@sebasguts unless you have plans to resurrect this PR, let's close it. I am not terribly fond of this feature anyway ;-). But of course if you or somebody else (@mohamed-barakat ) really, really needs this, we can get something like this in; but then the commit message should at least contain some motivation as to why this is useful. |
|
Actually, I would like to keep it for now. Will give more comments later. |
|
Sure, no hurry. It's not hurting us to have it open either :-) |
Added the possibility to parametrize chunks with variables and define their values when the chunks are included.