If you want the following behavior:
.ds DATE*FULL <modified date> The updated short date is \*[DATE*SHORT]. then I don't think that will be possible, since you can't do any complex processing inside a string invocation. If you are willing to treat the dates as macros instead of strings, like so: .DATE*FULL -set <modified date> The updated short date is .DATE*SHORT . then you could do all sorts of stuff, including calling out to the system for support. If you must have the dates as strings, then I would adopt a different model: .\" unsafe .\" ---------------------------------------------------------------- .de GET_DATE .ds TEMP_FILE /tmp/groff.\n($$ .sy date +'.ds DATE*DAY %-d%n.ds DATE*MONTH %-m%n.ds DATE*YEAR %Y%n.ds DATE*DAYNAME %A%n.ds DATE*DAYABBR %a%n.ds DATE*MONTHNAME %B%n.ds DATE*MONTHABBR %b' >\\*[TEMP_FILE] .so \\*[TEMP_FILE] .sy rm \\*[TEMP_FILE] .. .ds DATE*FULL \\*[DATE*DAYNAME], \\*[DATE*DAY] \\*[DATE*MONTHNAME] \\*[DATE*YEAR] .ds DATE*SHORT \\*[DATE*DAY] \\*[DATE*MONTHABBR] \\*[DATE*YEAR] .\" ---------------------------------------------------------------- .GET_DATE .sp 3c Today is \m[red]\*[DATE*FULL]\m[] (or \m[red]\*[DATE*SHORT]\m[] for short). and simply refrain from editing DATE*FULL, but only its components DATE*DAY, DATE*MONTH, etc. But I don't think this will really be any better than getting into the habit of always changing DATE*FULL and DATE*SHORT in lockstep. Alternatively, you could write a macro SET_DATE, which sets both DATE*FULL and DATE*SHORT, and you force yourself not to overwrite DATE*FULL but to call the SET_DATE macro instead.
