title: How can I parse this plaintext RP-style string into a more generic XML-style one?
body: <p>I'm making an app that will translate roleplaying-style messages into something much more generic. The user has the ability to specify their preferences, like:</p>
  
  <pre><code>Moves
   - /me &lt;move&gt;
   - *&lt;move&gt;*
  Speech
   - &lt;speech&gt;
   - "&lt;speech&gt;"
  Out-of-Character
   - [&lt;ooc&gt;]
   - ((ooc))
   - //ooc
  </code></pre>
  
  <p>I need to parse a message like this:</p>
  
  <pre><code>/me eats food "This is *munch* good!" [You're good at this]
  </code></pre>
  
  <p>or like this:</p>
  
  <pre><code>*eats food* This is *munch* good! ((You're good at this))
  </code></pre>
  
  <p>into a more generic, XML-like string like this:</p>
  
  <pre><code>&lt;move&gt;eats food &lt;speech&gt;This is &lt;move&gt;munch&lt;/move&gt; good!&lt;/speech&gt; &lt;ooc&gt;You're good at this&lt;/ooc&gt;&lt;/move&gt;
  </code></pre>
  
  <p>but with regard to which is inside which. For example:</p>
  
  <pre><code>*eats food "This is munch* good" // You're good at this
  </code></pre>
  
  <p>should be parsed as:</p>
  
  <pre><code>&lt;move&gt;eats food "This is munch&lt;/move&gt;&lt;speech&gt; good" &lt;/speech&gt;&lt;ooc&gt; You're good at this&lt;/ooc&gt;
  </code></pre>
  
  <p>even if that's not what the user intended. Note that the quotes in this last example weren't parsed because they didn't wrap a complete segment, and the current move segment had not finished by the time the first was encountered, and speech had already started when the second one was, and the second one didn't have another after it to surround a separate speech segment.</p>
  
  <p>I've tried doing this iteratively, recursively, with trees, and even with regexes, but I haven't found a solution that works like I want it to. <strong>How do I parse the above RP-style messages into the above generic XML-style messages?</strong></p>
  
  <p>Also important is that the spacing is preserved.</p>
  
  <p>Here are some other examples using the above-listed preferences:</p>
  
  <pre><code>I like roller coasters.
  [what are you like?]
  /me eats a hamburger // wanna grab lunch after this?
  *jumps up and down* This ((the party)) is great!
  /me performs *an action* within an action "And that's just fine [As is *an action* in ooc in speech]"
  And messages /me can change contexts // at any point
  [But ill-formatted ones *must be parsed] according "to* the rules"
  -And text formatted in &lt;non-specified ways&gt; is &amp;not treated; specially-
  </code></pre>
  
  <p>become:</p>
  
  <pre><code>&lt;speech&gt;I like roller coasters.&lt;/speech&gt;
  &lt;ooc&gt;what are you like?&lt;/ooc&gt;
  &lt;move&gt;eats a hamburger &lt;ooc&gt; wanna grab lunch after this?&lt;/ooc&gt;&lt;/move&gt;
  &lt;move&gt;jumps up and down&lt;/move&gt;&lt;speech&gt; This &lt;ooc&gt;the party&lt;/ooc&gt; is great!&lt;/speech&gt;
  &lt;move&gt;performs &lt;move&gt;an action&lt;/move&gt; within an action &lt;speech&gt;And that's just fine &lt;ooc&gt;As is &lt;move&gt;an action&lt;/move&gt; in ooc in speech&lt;/ooc&gt;&lt;/speech&gt;&lt;/move&gt;
  &lt;speech&gt;And messages &lt;move&gt;can change contexts &lt;ooc&gt; at any point&lt;/ooc&gt;&lt;/move&gt;&lt;/speech&gt;
  &lt;ooc&gt;But ill-formatted ones *must be parsed&lt;/ooc&gt;&lt;speech&gt; according &lt;speech&gt;to* the rules&lt;/speech&gt;&lt;/speech&gt;
  &lt;speech&gt;-And text formatted in &amp;lt;non-specified ways&amp;gt; is &amp;amp;not treated; specially-&lt;/speech&gt;
  </code></pre>