nbstata icon indicating copy to clipboard operation
nbstata copied to clipboard

Inline Stata code in Quarto

Open hugetim opened this issue 1 year ago • 1 comments

Now if we could get the option of inline Stata…

Originally posted by @friosavila in https://github.com/hugetim/nbstata/issues/37#issuecomment-2394444814

The Quarto docs state "This syntax works for any Jupyter kernel..." so I don't understand why it doesn't work, but it indeed doesn't. Have you tried submitting a Quarto issue about it?

hugetim avatar Oct 04 '24 22:10 hugetim

I went ahead and reported this here: https://github.com/quarto-dev/quarto-cli/issues/10979

hugetim avatar Oct 04 '24 23:10 hugetim

Update: I think the issue is due to missing kernel functionality in 'nbstata' that should be straightforward to implement. I hope to release it by the end of the month.

See: https://github.com/quarto-dev/quarto-cli/issues/10979#issuecomment-2398043525

hugetim avatar Oct 07 '24 22:10 hugetim

The plan is to pass any inline expressions to sfi.SFIToolkit.macroExpand, making use of the '= exp' local expansion operator.

So, given the following line in a .qmd file, assuming that the Stata scalars x and y have already been defined

Testing inline `{stata} x + y`.

I'll get the output to replace the inline code expression with from this Python:

output = sfi.SFIToolkit.macroExpand("""`=x + y'""")

Unfortunately, it seems we won't be able to use locals in inline Stata code, due to the backtick syntax clash. But we should be able to use scalars, globals, and also "return" macros.

hugetim avatar Oct 07 '24 23:10 hugetim

That is awesome!

May I suggest to also allow for display and globals?

And perhaps mata ‘Stata mata x’ Allowing to show the content of x?

On Mon, Oct 7, 2024 at 7:12 PM Tim Huegerich @.***> wrote:

The plan is to pass any inline expressions to sfi.SFIToolkit.macroExpand https://www.stata.com/python/api18/SFIToolkit.html#sfi.SFIToolkit.macroExpand, making use of the '= exp' local expansion operator.

So, given the following line in a .qmd file, assuming that the Stata scalars x and y have already been defined

Testing inline {stata} x + y.

I'll get the output to replace the inline code expression with from this Python:

output = sfi.SFIToolkit.macroExpand("""`=x + y'""")

Unfortunately, it seems we won't be able to use locals in inline Stata code, due to the backtick syntax clash. But we should be able to use scalars, globals, and also "return" macros https://www.stata.com/python/api18/Macro.html#sfi.Macro.getGlobal.

— Reply to this email directly, view it on GitHub https://github.com/hugetim/nbstata/issues/50#issuecomment-2398107872, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASZKKFSXHJVJTWITBK3MTIDZ2MIM7AVCNFSM6AAAAABPMW5UYWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJYGEYDOOBXGI . You are receiving this because you were mentioned.Message ID: @.***>

friosavila avatar Oct 07 '24 23:10 friosavila

May I suggest to also allow for display and globals? And perhaps mata ‘Stata mata x’ Allowing to show the content of x?

Globals should already be covered by my current plan. Likewise for Mata if you pass the relevant information to Stata first (such as with st_numscalar or 'st_matrix').

What do you have in mind using display for? If it's something like formatting a number, you should be able to save a number in the correct format to a string scalar (using strofreal(n,s)).

But the idea is that you can use any Stata expression in the inline code (except that locals are not allowed). I think that will read better than having Stata commands like "display" and "mata" in there (and it would also be much more complicated to allow those, I think).

hugetim avatar Oct 08 '24 01:10 hugetim

On second thought, maybe we should try to match MarkStat's features for inline code:

You can quote results by including inline code as part of your narrative, using the syntax `s [fmt] expression`, where fmt is an optional format, followed by an expression. The markstat command will generate code to evaluate the expression using Stata’s display command, and will splice the output inline with the text. For example after running a regression you can cite R-squared by coding `s e(r2)`. If you prefer to display the value with 2 decimal places only, use `s %5.2f e(r2)`. Consistent with our treatment of Mata as a first class citizen, you can also include inline Mata code using the same syntax, but with an m instead of an s. The markstat command will generate a printf() function call to display the expression with the given format. If the format is omitted it defaults to %s, so the expression should yield a string.

(We could use mata's sprintf, saving to a scalar which we can then retrieve via Python.)

hugetim avatar Oct 08 '24 17:10 hugetim

Decided to keep it simple for now and just support the Stata display syntax (with no special mata support).

hugetim avatar Oct 12 '24 05:10 hugetim

Good news: we're able to directly use Stata's display (so that you "can use all the features of display that make sense," as Stata's docs put it) like this: https://github.com/hugetim/nbstata/blob/12fc23f00fcb14df59d6d12ea910ea45259a8ecb/nbstata/stata_more.py#L181

For future consideration:

For Mata, my current thought on the syntax is to make the sprintf function explicit (but make the 'mata' implicit, to save typing). So it would look like this:

The first coefficient is `{stata} sprintf("%10.0g", coef[1])`.

Thoughts? This provides flexibility to include multiple variables in a single inline code statement, similar to display.

Alternatively, the syntax could more closely mimic MarkStat, like {stata} mata %10.0g coef[1] (or just {stata} mata coef[1]). Is that better? Less flexibility (and also error messages will be more difficult to interpret) but also less typing.

Either way, this plan will provide inline code feature parity with MarkStat, except that we won't be able to support SMCL.

hugetim avatar Oct 12 '24 05:10 hugetim

Thank you. This is awesome Any chance of one other request? I know with quarto we can set environmental variables then feed them into python or R Do you think that could be done for nbstata too?

On Sat, Oct 12, 2024 at 1:40 AM Tim Huegerich @.***> wrote:

Closed #50 https://github.com/hugetim/nbstata/issues/50 as completed.

— Reply to this email directly, view it on GitHub https://github.com/hugetim/nbstata/issues/50#event-14615910355, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASZKKFQI6TJWXZE33WHEV7DZ3CY5HAVCNFSM6AAAAABPMW5UYWVHI2DSMVQWIX3LMV45UABCJFZXG5LFIV3GK3TUJZXXI2LGNFRWC5DJN5XDWMJUGYYTKOJRGAZTKNI . You are receiving this because you were mentioned.Message ID: @.***>

friosavila avatar Oct 12 '24 08:10 friosavila