type Doc = <doc>Text;;
type Text = [ (Char | (Letter+ ' '* Note))* ];;
type Letter = 'a'--'z' | 'A'--'Z';;
type Note = <note>[ PCDATA ];;

type Flow = [ (Char | <ref no=Int>[ PCDATA ])* ];;
type Notes = [ <note no=Int>[ PCDATA ]* ];;
type Result = <doc>[ <body>Flow <notes>Notes ];;

let fun format (<doc>s : Doc) : Result = 
  let (body,notes) = text (s,1) in
  <doc>[ <body>body <notes>notes ];;

let fun text ( (Text,Int) -> (Flow,Notes) )
 | ([ pre::Char*? (word::Letter+ ' '* <note>n); rem ], count) ->
      let (body,notes) = text (rem, count + 1) in
      (pre @ [<ref no=count>word] @ body, 
       [<note no=count>n] @ notes)
 | (body,_) -> (body, []);;

try
match load_xml "tests/notes.xml" with
 | x & Doc -> format x
 | _ -> raise "Invalid input document"
with _ -> "Bon ca va";;

