How are taproot scripts represented in general?

I’m pretty familiar with the opcode style of writing down scripts. I can understand the stack-based language nature of bitcoin script where you can write down different script spend paths via ifs like this:

   <3, publicKey1, publicKey2, publicKey3, 2, ...> OP_CHECKMULTISIGVERIFY
   <3, publicKey1, publicKey2, publicKey3, 1, ...> OP_CHECKMULTISIGVERIFY

which can then be executed with a scriptSig like "ignored" key1Sig 1 or "ignored" key2Sig 0.

However, I don’t know a good way to write down spend paths for taproot. Eg, if I want to say have a key spend-path using a threshold signature, and I want 3 script spend-paths, one of which has two nested script spend-paths, what’s a good way to represent that. Or rather, how has that been represented in the past? And how does a transaction spending an output select which taproot script spend-path it wants to use? In the current script, one of the if branches is selected with either 1 or 0 pushed onto the stack via the scriptSig. In Taproot, how is the spend path selected?