let rec build_node_tree (doc: doc)
  : node_ref * (node_ref * node) list =
    let dr = fresh_node_ref () in
    match doc with
    | Para(id, text) ->
        (dr, [ (dr, Para_node(id, text)) ])
    | Link(id, u, text) ->
        (dr, [ (dr, Link_node(id, u, text)) ])
    | Textbox(id, text) ->
        (dr, [ (dr, Textbox_node(id, text, [])) ])
    | Button(id, text) ->
        (dr, [ (dr, Button_node(id, text, [])) ])
    | Inl_script(id, e) ->
        (dr, [ (dr, Inl_script_node(id, e, false)) ])
    | Rem_script(id, u) ->
        (dr, [ (dr, Rem_script_node(id, u, false)) ])
    | Div(id, subdocs) ->
        let (drs, nhs) = List.split (List.map build_node_tree subdocs) in
        (dr, (dr, Div_node(id, drs)) :: List.flatten nhs)