ID:259423
 
BYOND's built-in text macros are amazing, but I've been thinking: There are a couple of problems here. One is that documentation is slightly sparse on them; I was just thinking, after reading Jmurph's post in Bug Reports about \s, that it's not clear from the reference whether \s is meant for objects or numbers or both.

Here's the other problem: For as many helpful macros as there are, there could be more. For example, sometimes a user may want \es instead of \s. In my current project, I'm facing multiple situations where I want to end a word with -y or -ies depending on whether the number before it is plural, and a \y macro would be just perfect for that.

Now obviously, there's no way every conceivable useful text macro could be added to DM; it'd be pointless. But what if there was a structure in place by which we could define our own? Imagine this:
proc/MACRO_y(var/before,var/after)
if(isnum(before))
return (before==1)?"ies":"y"
if(istype(before,/atom))
var/atom/b=before
return (b.gender=="plural")?"ies":"y"
return

In this scenario, every proc set up with MACRO_n would become a valid text macro. Arguments sent to the proc would include the last bracketed input to go before, and the next one following (including as an argument, like \macro[arg]). So the text string "You own [n] bunn\y." will call the global proc MACRO_y(n,null).

If you don't want to restrict the possible names for procs, another solution is to introduce the macro keyword to the server (it's currently just in the client, but there's no reason it couldn't mean something different to the server) and define the proc as macro/y, or perhaps macro/text/y.

I suspect this wouldn't be too difficult to implement, as basically all this would do would be to expand "You own [n] bunn\y." to "You own [n] bunn[MACRO_y(n,null)]." There are only a couple of gotchas: First, you have to take care that the before and after variables aren't affected by these substitutions, so if you use more than one text macro between a pair of brackets they'll still expand correctly. Second, a macro should not be allowed to be self-recursive; if a second call to MACRO_y pops up on the call stack when one's already there, it should return a blank string. Whether or not you'd want to allow users to override the existing macros is a question best answered by somebody else.

Lummox JR

Yeah. Plurals and verb forms are a pain and extendable macros would be nice. We'll definitely put this excellent suggestion on the List.

--Dan
In response to Dan
Dan wrote:
Yeah. Plurals and verb forms are a pain and extendable macros would be nice. We'll definitely put this excellent suggestion on the List.

Cool! I made a good suggestion for once!

I didn't even think about verb forms, but you're right; they're even worse, because they follow the opposite rules.
macro/vs(before,after)
if(isnum(before))
return (before==1)?"s":""
if(istype(before,/atom))
var/atom/b=before
return (b.gender!="plural")?"s":""
return ""
macro/ves(before,after)
if(isnum(before))
return (before==1)?"es":""
if(istype(before,/atom))
var/atom/b=before
return (b.gender!="plural")?"es":""
return ""

I can imagine this coming in handy for complex battle engines.
"[attacker] throw\vs \a [projectile]!"
"[defender] catch\ves [projectile]!"
"[attacker] feint\vs! [defender] flinch\ves!"

It occurs to me that you might want to set up such a system so that if the "after" value immediately follows the macro, like \macro[arg], it's treated as an argument to the macro and not displayed separately. This way, the macro proc can decide whether to show it or not. It may be more desirable to give the macro proc three arguments, as such:
macro/x(before,arg,after)

If you did this, \x[n] would not display the value of n unless the macro was intended to do so. Since this type of macro is probably rare, an alternative is to define the syntax for it as macro/arg/x, indicating it takes an argument. This would prevent other macros from getting screwed up in rare but cases where [] has to follow another macro without a space.

Of course, I just realized that another benefit of the macro/x syntax is that the arguments (before,after) can just be left out and assumed to be there. That could make macros even easier to write.

Lummox JR
In response to Lummox JR
I think you are on to something, by golly. The format you propose is very nice in that it's easilly expandable, efficient, and *gasp* easy to understand.
While I am sure it is certainly not a big fish on Dantom's plate, it would be a nice feature for us lazzy text users;-)

-James