Right now, what happens is that the "show" co-opts my CDS keyword as part of the show statement, because the parser for show statements looks for the end of a line as its cue that the statement is over.
Finding the cause of this my-code-skippage was very very very interesting, since I did not know what a parser was until, like, MAYBE 72 hours before that moment. However, being this much of a novice also means that I'm not entirely sure I'm on the right track as far as "using this information to solve my problem" goes.
If you're reading this and know things about how ren'py works internally: could you confirm/deny something for me? Is it possible to overwrite ren'py's inbuilt "show" parser with my own, extremely similar parser (which adds one "if" statement which checks for my keyword), without directly editing the source code?
I'll run through what I've tried (skip to the end and check out questions 1 and 4 if you're pretty sure the answer is "of course not??" and don't need to read what I've tried), but first: I'm not, like, vehemently opposed to editing the source code, I guess? I don't think? But also, it's easier to keep track of what's weirdo homebrew handle-with-care-type code if it's all inside my project folder, so I'd prefer to do that where possible. Just, like, instinctively.
(I'm also sensing that the answer to this question might possibly teach me something, which would be exciting.)
Anyway: details: I've gathered that ren'py's show parser is kept track of like this:
renpy.parser.statements is a ParseTrie object. It acts as the root of the trie that keeps track of parsers (and is presumably accessed when it's time to decide which parser to use for a given statement).
The show parser is added to renpy.parser.statements using statements.add("show", f), where f is the show_statement parser function itself(, I guess? I have never actually written a decorator; be nice to me. I'm PRETTY sure that f is what this decorator calls "self", and that "self" in this case would refer to the function being wrapped by the decorator. Probably).
This adds "show" to statements.words, which is a dictionary of strings and other stuff. Crucially, this SHOULD mean that "show" is a key contained directly in statements.words, and the other half of its dictionary entry (which... is... another ParseTrie which keeps the parser function as its "default" value?) should be directly tied to its presence, right?
What I've TRIED to do is:
- define my own show parser in a python early block
- del renpy.parser.statements.words["show"]
- renpy.parser.statements.add("show", my_show_parser)
Possibly this is obvious to people who aren't me, but: okay: the "del" line doesn't break anything (which is what I'd expect if, say, I weren't allowed to directly access ren'py's stuff in this manner), BUT it also doesn't seem to do anything, because I gently placed a print() inside my custom parser so I'd know when it was being used, and it super isn't. But show statements still work, which wouldn't make sense if I HAD managed to divest the show parser from the thing that keeps track of where parsers are.
So I'm getting the feeling that either "del"-ing statements.words["show"] doesn't hide the inbuilt show statement parser in any meaningful way at all, or it would if I did it at exactly the right time but my timing is off... OR that I'm not even actually "del"-ing anything at all, and my attempts are so ineffectual that ren'py isn't bothering to warn me that what I'm trying to do won't work.
Having written this out, I feel like there are 3 layers of question here:
1. Can code written inside a project folder directly grab ren'py with its weird little hands and change stuff for which there isn't a config variable or something of that nature? In the general sense?
(Okay, so if the answer is "no" there's only ONE layer of question, but IF IT'S YES:)
2. WHEN does ren'py decide which parser to use for a given type of statement? My self-taught code-deciphering skills are at their limit here.
3. "Should" the "del" --> "statements.add" approach work? As in, assuming that I got the timing right and did this AFTER "show" had already been added, but BEFORE any of my script was actually parsed, would I be able to redirect the parsing of show statements in my script by going "okay now get rid of the key/value pair, in the "words" dictionary belonging to the "statements" object, whose key is "show". Okay, now ADD a thing to statements using the key "show"; here is the second argument, it is a function."........??
(......4. If I have to directly change the source code, I should only have to change renpy.parser.show_statement, right?)
If you're asking yourself why someone would use THIS MUCH energy just to avoid using more linebreaks in their script: 1. stubborn 2. got curious 3. incapable of learning unless sufficiently motivated by the prospect of future convenience; not convinced this information won't come in handy at some point even if I give up on this particular Dubious Idea.
Thank you for taking the time to read! If you can, please help me learn something practical from all this...