///|
/// Decode only the entities emitted by our XML writer, with ampersand last so
/// escaped source text cannot be decoded twice.
fn scene_attribute_text(value : String) -> String {
  value
  .replace_all(old="<", new="<")
  .replace_all(old=">", new=">")
  .replace_all(old=""", new="\"")
  .replace_all(old="	", new="\t")
  .replace_all(old="
", new="\n")
  .replace_all(old="
", new="\r")
  .replace_all(old="&", new="&")
}

///|
fn scene_attribute(tag : String, name : String) -> String? {
  let prefix = " " + name + "=\""
  guard tag.find(prefix) is Some(start) else { return None }
  let tail = tag[start + prefix.length():]
  guard tail.find("\"") is Some(end) else { return None }
  Some(scene_attribute_text(tail[:end].to_owned()))
}

///|
/// Read final path bindings from this module's generated, line-oriented writer
/// output. This is not an XML parser for external SVG. Source text is escaped
/// before this step; only path tags marked by the connector finalizer qualify.
/// The caller already bounds the complete canonical artifact by output_units.
fn final_connector_bindings(
  canonical : String,
) -> Array[(String, String, String?)] {
  let result = []
  for line in canonical.split("\n") {
    let tag = line.trim_start().to_owned()
    if !tag.has_prefix(""),
      ]),
      @writer.element("path", attrs=[("d", "unmarked")]),
      @writer.element("path", attrs=[
        ("data-connector-route", "M0 0 L10 10"),
        ("d", "M0 0 Q5 3 10 10"),
        ("mask", "url(#prefix-<mask)"),
      ]),
    ]),
  )
  assert_eq(final_connector_bindings(source), [
    ("M0 0 L10 10", "M0 0 Q5 3 10 10", Some("url(#prefix-<mask)")),
  ])
}