HTML-Gumbo

 view release on metacpan or  search on metacpan

lib/HTML/Gumbo.xs  view on Meta::CPAN

    FREETMPS;
    LEAVE;

    return res;
}

STATIC void
tree_to_tree(pTHX_ PerlHtmlGumboType type, GumboNode* node, void* ctx) {
    SV** out = (SV**) ctx;
    if ( type == PHG_TEXT ) {
        if ( node->type == GUMBO_NODE_COMMENT ) {
            SV* element = new_html_element(aTHX_ node);
            push_element(aTHX_ *out, element);
            SvREFCNT_dec(element);
        } else {
            push_text_element(aTHX_ *out, node->v.text.text, 0);
        }
    }
    else if ( type == PHG_ELEMENT_START && node->type == GUMBO_NODE_DOCUMENT ) {
        GumboDocument* doc = &node->v.document;
        if ( doc->has_doctype ) {
            SV* element = new_html_element_doctype(aTHX_ doc);
            push_element(aTHX_ *out, element);
            SvREFCNT_dec(element);
        }
    }
    else if ( type == PHG_ELEMENT_END && node->type == GUMBO_NODE_DOCUMENT ) {
    }
    else if ( type == PHG_ELEMENT_START ) {
        SV* element = new_html_element(aTHX_ node);
        push_element(aTHX_ *out, element);
        *out = element;
    }
    else if ( type == PHG_ELEMENT_END ) {
        SV* parent = get_element_parent(aTHX_ *out);
        SvREFCNT_dec(*out);
        *out = parent;
    }
    return;
}

STATIC void
tree_to_callback(pTHX_ PerlHtmlGumboType type, GumboNode* node, void* ctx) {
    dSP;
    SV* cb = (SV*) ctx;

    if ( type == PHG_ELEMENT_END && PHG_IS_VOID_ELEMENT(node->v.element.tag) )
        return;

    ENTER;
    SAVETMPS;

    PUSHMARK(SP);
    if ( type == PHG_TEXT ) {
        switch ( node->type ) {
            case GUMBO_NODE_TEXT:
                mXPUSHs(newSVpvs("text"));break;
            case GUMBO_NODE_WHITESPACE:
                mXPUSHs(newSVpvs("space"));break;
            case GUMBO_NODE_CDATA:
                mXPUSHs(newSVpvs("cdata"));break;
            case GUMBO_NODE_COMMENT:
                mXPUSHs(newSVpvs("comment"));break;
            default:
                croak("Unknown node type");
        }
        mXPUSHs(newSVpvz8( node->v.text.text ));
    }
    else if ( type == PHG_ELEMENT_START && node->type == GUMBO_NODE_DOCUMENT ) {
        GumboDocument* doc = &node->v.document;
        mXPUSHs(newSVpvs("document start"));
        if ( doc->has_doctype ) {
            HV* h = newHV();
            mXPUSHs(newRV_noinc((SV*)h));
            (void)hv_stores(h, "name", newSVpvz8( doc->name ));
            (void)hv_stores(h, "public", newSVpvz8( doc->public_identifier ));
            (void)hv_stores(h, "system", newSVpvz8( doc->system_identifier ));
        } else {
            mXPUSHs(&PL_sv_undef);
        }
    }
    else if ( type == PHG_ELEMENT_END && node->type == GUMBO_NODE_DOCUMENT ) {
        mXPUSHs(newSVpvs("document end"));
    }
    else if ( type == PHG_ELEMENT_START ) {
        int i;
        GumboVector* attrs = &node->v.element.attributes;
        GumboStringPiece tag = get_tag_name(&node->v.element);
        AV* for_attrs = newAV();

        mXPUSHs(newSVpvs("start"));
        mXPUSHs(newSVpvn8( tag.data, tag.length ));
        mXPUSHs(newRV_noinc((SV*)for_attrs));
        for (i = 0; i < attrs->length; i++) {
            GumboAttribute* attr = (GumboAttribute*) attrs->data[i];
            av_push(for_attrs, newSVpvz8( attr->name ));
            av_push(for_attrs, newSVpvz8( attr->value ));
        }
    }
    else if ( type == PHG_ELEMENT_END ) {
        GumboStringPiece tag = get_tag_name(&node->v.element);
        mXPUSHs(newSVpvs("end"));
        mXPUSHs(newSVpvn8( tag.data, tag.length ));
    }
    else {
        croak("Unknown element type");
    }

    PUTBACK;

    call_sv(cb, G_DISCARD);

    FREETMPS;
    LEAVE;

    return;
}

STATIC
GumboOptions
format_options(pTHX_ HV* opts) {



( run in 0.588 second using v1.01-cache-2.11-cpan-39bf76dae61 )