text-tags 0.1.0

A lightweight, text-tag markup parser
Documentation
/*
 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 */
use seq_map::SeqMap;
use text_tags::{parse, ArgValue, Element, Node};

#[test]
fn text_only() {
    let input = "Just plain text.";
    let ast = parse(input);
    assert_eq!(ast, vec![Node::Text("Just plain text.".into())]);
}

#[test]
fn single_element_no_args() {
    let input = "[b]bold[/b]";
    let ast = parse(input);
    assert_eq!(ast.len(), 1);
    if let Node::Element(e) = &ast[0] {
        assert_eq!(e.name, "b");
        assert!(e.args.is_empty());
        assert_eq!(e.children, vec![Node::Text("bold".into())]);
    } else {
        panic!("Expected Element");
    }
}

#[test]
fn element_with_various_args() {
    let input = r#"[tag #abc123 val=42 pi=3.14 on=true name=Test label="Hi"]x[/tag]"#;
    let ast = parse(input);
    if let Node::Element(e) = &ast[0] {
        assert_eq!(e.args.get("value"), Some(&ArgValue::Hex("#abc123".into())));
        assert_eq!(e.args.get("val"), Some(&ArgValue::Int(42)));
        assert_eq!(e.args.get("pi"), Some(&ArgValue::Fixed(3.14.into())));
        assert_eq!(e.args.get("on"), Some(&ArgValue::Bool(true)));
        assert_eq!(e.args.get("name"), Some(&ArgValue::Keyword("Test".into())));
        assert_eq!(e.args.get("label"), Some(&ArgValue::Str("Hi".into())));
    } else {
        panic!("Expected Element");
    }
}

#[test]
fn nested_elements() {
    let input = "[a][b]x[/b]y[/a]";
    let ast = parse(input);
    if let Node::Element(e) = &ast[0] {
        assert_eq!(e.name, "a");
        assert_eq!(e.children.len(), 2);
    } else {
        panic!("Expected Element");
    }
}


#[test]
fn mixed_escaped_and_real_brackets() {
    let input = r#"Start \[notatag] then [b]bold\[still] text[/b] end"#;
    let ast = parse(input);

    assert_eq!(
        ast,
        vec![
            Node::Text("Start [notatag] then ".into()),
            Node::Element(Element {
                name: "b".into(),
                args: SeqMap::new(),
                children: vec![
                    Node::Text("bold[still] text".into())
                ],
            }),
            Node::Text(" end".into()),
        ]
    );
}