Extract XML element name from start_tag/self_closing_tag children.
| 3324 | |
| 3325 | // Extract XML element name from start_tag/self_closing_tag children. |
| 3326 | static char *find_xml_element_name(CBMArena *a, TSNode node, const char *source) { |
| 3327 | uint32_t nc = ts_node_child_count(node); |
| 3328 | for (uint32_t i = 0; i < nc; i++) { |
| 3329 | TSNode child = ts_node_child(node, i); |
| 3330 | const char *ck = ts_node_type(child); |
| 3331 | if (strcmp(ck, "start_tag") == 0 || strcmp(ck, "self_closing_tag") == 0 || |
| 3332 | strcmp(ck, "STag") == 0 || strcmp(ck, "EmptyElemTag") == 0) { |
| 3333 | uint32_t tnc = ts_node_child_count(child); |
| 3334 | for (uint32_t j = 0; j < tnc; j++) { |
| 3335 | TSNode tag = ts_node_child(child, j); |
| 3336 | const char *tk = ts_node_type(tag); |
| 3337 | if (strcmp(tk, "tag_name") == 0 || strcmp(tk, "Name") == 0) { |
| 3338 | return cbm_node_text(a, tag, source); |
| 3339 | } |
| 3340 | } |
| 3341 | } |
| 3342 | } |
| 3343 | // Fallback: try "Name" field directly for some XML grammars |
| 3344 | TSNode name_child = cbm_find_child_by_kind(node, "Name"); |
| 3345 | if (!ts_node_is_null(name_child)) { |
| 3346 | return cbm_node_text(a, name_child, source); |
| 3347 | } |
| 3348 | return NULL; |
| 3349 | } |
| 3350 | |
| 3351 | // Extract text from an atx_heading node (# Title). |
| 3352 | static char *extract_atx_heading_text(CBMArena *a, TSNode node, const char *source) { |
no test coverage detected