indexing description : "Objects that ..." author : "$Author$" date : "$Date$" revision : "$Revision$" class XML2WIKITEXT inherit XM_CALLBACKS create make feature {NONE} -- Initialization make -- Initialize `Current'. local x: XM_EIFFEL_PARSER do create x.make x.set_callbacks (Current) parser := x end parser: XM_EIFFEL_PARSER feature -- Access url_resolver: URL_RESOLVER assign set_url_resolver product_name: STRING assign set_product_name inside_help_element: BOOLEAN -- Is inside element? --| this is needed to handle differently according to the context inside_preformatted_element: BOOLEAN -- Is inside a preformatted element? --| such as code, code_block .. enter_preformatted_element require not_inside_preformatted_element: not inside_preformatted_element do inside_preformatted_element := True end exit_preformatted_element require inside_preformatted_element: inside_preformatted_element do inside_preformatted_element := False end output_switch: XMLDOC_OUTPUT is_valid_output_scope: BOOLEAN do Result := output_switch = Void or else output_switch.matched (product_name) end feature -- Element change set_output_switch (o: like output_switch) require switched: o /= Void implies output_switch = void do output_switch := o end set_product_name (v: like product_name) -- Set `product_name' do if v = Void then product_name := Void else product_name := v.twin product_name.left_adjust product_name.right_adjust product_name.to_lower if product_name.is_empty then product_name := Void end end end set_url_resolver (v: like url_resolver) -- set `url_resolver' to `v' do url_resolver := v end feature -- Basic operations process_filename (fn: STRING) local l_xml_content: STRING f: RAW_FILE do create f.make (fn) if f.exists and then f.is_readable then f.open_read from create l_xml_content.make (f.count) f.start until f.exhausted or f.end_of_file loop f.read_stream (512) l_xml_content.append (f.last_string) end f.close end if l_xml_content /= Void then if url_resolver = Void then create url_resolver end url_resolver.current_filename := fn process_string (l_xml_content) url_resolver.current_filename := Void end end process_string (s: !STRING) -- Process xmldoc contained in string `s' local retried: BOOLEAN em: EXCEPTION_MANAGER do if not retried then reset parser.parse_from_string (s) else create em if {e: EXCEPTION} em.last_exception then exception := e raise_exception_error ("Convertion failed [" + e.meaning + "]", e) else raise_exception_error ("Convertion failed: exception ...", Void) end end rescue retried := True retry end feature -- Result reset is -- Reset results do if parser /= Void then parser.reset end if errors /= Void then errors.wipe_out end if opened_items /= Void then opened_items.wipe_out end inside_preformatted_element := False exception := Void page := Void end raise_error (m: STRING) local s: STRING err: ERROR do create err create s.make_from_string (m) if parser /= Void then err.position := parser.byte_position end err.message := s errors.extend (err) if parser /= Void then err.position := parser.byte_position end end raise_error_unavailable (m: STRING) local err: ERROR_UNAVAILABLE do create err err.associated_tag := m err.message := "unavailable: " + m if parser /= Void then err.position := parser.byte_position end errors.extend (err) end raise_exception_error (m: STRING; e: EXCEPTION) local err: ERROR_EXCEPTION do create err err.message := m if e /= Void then err.exception := e end if parser /= Void then err.position := parser.byte_position end errors.extend (err) end exception: EXCEPTION errors: LIST [ERROR] page: XMLDOC_PAGE opened_items: ARRAYED_STACK [XMLDOC_ITEM] last_content: XMLDOC_CONTENT do if not opened_items.is_empty then Result ?= opened_items.item end end last_but_one_item: XMLDOC_ITEM local i: like last_item do if not opened_items.is_empty then i := opened_items.item remove_last_item if not opened_items.is_empty then Result := opened_items.item end push_last_item (i) end end last_item: XMLDOC_ITEM do if not opened_items.is_empty then Result := opened_items.item end end remove_last_item do opened_items.remove end push_last_item (i: like last_item) do opened_items.extend (i) end feature -- Document on_start is -- Called when parsing starts. do create {LINKED_LIST [ERROR]} errors.make create opened_items.make (10) page := Void end on_finish is -- Called when parsing finished. do if page = Void then page ?= last_item end check page_attached: page /= Void end end on_xml_declaration (a_version: STRING; an_encoding: STRING; a_standalone: BOOLEAN) is -- XML declaration. do end feature -- Errors on_error (a_message: STRING) is -- Event producer detected an error. do raise_error (a_message) end feature -- Meta on_processing_instruction (a_name: STRING; a_content: STRING) is -- Processing instruction. do end on_comment (a_content: STRING) is -- Processing comment. -- Atomic: single comment produces single event do end feature -- Tag on_start_tag (a_namespace: STRING; a_prefix: STRING; a_local_part: STRING) is -- Start of start tag. local l_paragraph: XMLDOC_PARAGRAPH l_img: XMLDOC_IMAGE l_parent_item: like last_item l_item: like last_item l_list_item: XMLDOC_LIST_ITEM l_table: XMLDOC_TABLE l_row: XMLDOC_TABLE_ROW l_cell: XMLDOC_TABLE_CELL l_content: like last_content l_meta_data: XMLDOC_METADATA do if is_valid_output_scope then l_content := last_content if l_content /= Void then remove_last_item if l_content.is_empty then l_content := Void end end check last_content = Void end l_parent_item := last_item if l_content /= Void then if {l_w_content: XMLDOC_WITH_CONTENT} l_parent_item then l_w_content.add_item (create {XMLDOC_TEXT}.make (l_content)) else -- check only_paragraph: False end --| Let's ignore this content end l_content := Void end inspect tag_to_id (a_local_part) when id_document then create page.make push_last_item (page) l_item := page when id_meta_data then create {XMLDOC_METADATA} l_meta_data.make if {l_page: XMLDOC_PAGE} last_item then l_page.set_meta_data (l_meta_data) end push_last_item (l_meta_data) l_item := Void when id_meta then if {l_meta: XMLDOC_META} (create {XMLDOC_META}.make) then if {ot_meta_data: XMLDOC_METADATA} last_but_one_item then ot_meta_data.add_meta (l_meta) end push_last_item (l_meta) else check False end end l_item := Void when id_list then create {XMLDOC_LIST} l_item.make push_last_item (l_item) when id_item then if {lst: XMLDOC_LIST} last_item then create {XMLDOC_LIST_ITEM} l_list_item.make lst.add_item (l_list_item) push_last_item (l_list_item) l_item := Void else check False end end when id_content then create {XMLDOC_COMPOSITE_TEXT} l_item.make push_last_item (l_item) l_item := Void -- if {l_heading: XMLDOC_HEADING} last_item then -- --| content is the heading itself -- l_item := Void -- else -- check False end -- end when id_table then create {XMLDOC_TABLE} l_item.make push_last_item (l_item) when id_row then if {table: XMLDOC_TABLE} last_item then create {XMLDOC_TABLE_ROW} l_row.make table.add_row (l_row) push_last_item (l_row) l_item := Void else check False end end when id_cell then if {table_row: XMLDOC_TABLE_ROW} last_item then create {XMLDOC_TABLE_CELL} l_cell.make table_row.add_cell (l_cell) push_last_item (l_cell) l_item := Void else check False end end when id_info then create {XMLDOC_INFO} l_item.make push_last_item (l_item) when id_code_block then create {XMLDOC_CODE_BLOCK} l_item.make push_last_item (l_item) enter_preformatted_element when id_code then create {XMLDOC_CODE} l_item.make push_last_item (l_item) -- enter_preformatted_element when id_note then create {XMLDOC_NOTE} l_item.make push_last_item (l_item) when id_output then set_output_switch (create {XMLDOC_OUTPUT}.make) l_item := Void when id_paragraph then create {XMLDOC_PARAGRAPH} l_item.make push_last_item (l_item) when id_sample then create {XMLDOC_SAMPLE} l_item.make push_last_item (l_item) when id_seealso then create {XMLDOC_SEEALSO} l_item.make push_last_item (l_item) when id_tip then create {XMLDOC_TIP} l_item.make push_last_item (l_item) when id_warning then create {XMLDOC_WARNING} l_item.make push_last_item (l_item) when id_line_break then create {XMLDOC_LINE_BREAK} l_item.make push_last_item (l_item) when id_image then create l_img.make if {img_link: XMLDOC_IMAGE_LINK} last_item then img_link.set_image (l_img) l_item := Void else l_item := l_img end push_last_item (l_img) when id_heading then create {XMLDOC_HEADING} l_item.make push_last_item (l_item) when id_label then create {XMLDOC_LABEL} l_item.make push_last_item (l_item) when id_anchor then create {XMLDOC_ANCHOR} l_item.make push_last_item (l_item) when id_cluster_name then create {XMLDOC_CLUSTER_NAME} l_item.make push_last_item (l_item) when id_class_name then create {XMLDOC_CLASS_NAME} l_item.make push_last_item (l_item) when id_feature_name then create {XMLDOC_FEATURE_NAME} l_item.make push_last_item (l_item) when id_bold then create {XMLDOC_BOLD} l_item.make push_last_item (l_item) when id_italic then create {XMLDOC_ITALIC} l_item.make push_last_item (l_item) when id_underline then create {XMLDOC_UNDERLINE} l_item.make push_last_item (l_item) when id_span then create {XMLDOC_SPAN} l_item.make push_last_item (l_item) when id_div then create {XMLDOC_DIV} l_item.make push_last_item (l_item) when id_link then create {XMLDOC_LINK} l_item.make push_last_item (l_item) when id_image_link then create {XMLDOC_IMAGE_LINK} l_item.make push_last_item (l_item) when id_url, id_alignment, id_style, id_width, id_height, id_border, id_size, id_legend, id_target, id_anchor_name, id_alt_text then --| handle by on_end_tag push_last_item (create {XMLDOC_UNUSED}.make (a_local_part)) l_item := Void when id_string, id_number, id_character, id_reserved_word, id_local_variable, id_symbol, id_local_variable_quoted, id_generics, id_contract_tag, id_indexing_tag, id_keyword, id_syntax, id_compiler_error, id_sub_script, id_comment then if not inside_help_element then create {XMLDOC_CODE_ENTITY} l_item.make (a_local_part) push_last_item (l_item) if {l_code: XMLDOC_CODE} l_parent_item then l_code.add_item (l_item) l_item := Void elseif {l_code_b: XMLDOC_CODE_BLOCK} l_parent_item then l_code_b.add_item (l_item) l_item := Void elseif {l_code_entity: XMLDOC_CODE_ENTITY} l_parent_item then l_code_entity.add_item (l_item) l_item := Void elseif {l_code_fake: XMLDOC_COMPOSITE_TEXT} l_parent_item then l_code_fake.add_item (l_item) l_item := Void elseif {l_unav: XMLDOC_UNAVAILABLE} l_parent_item then -- l_item := Void else check error: False end end else push_last_item (create {XMLDOC_UNAVAILABLE}.make (a_local_part)) raise_error ("Element <" + a_local_part + "> inside help element") l_item := last_item end else if tag_to_id (a_local_part) = id_help then inside_help_element := True end push_last_item (create {XMLDOC_UNAVAILABLE}.make (a_local_part)) raise_error_unavailable (a_local_part) l_item := last_item end if l_item /= Void then check l_item /= Void implies l_item = last_item end if {l_ppage: XMLDOC_PAGE} l_parent_item then if {l_comp: XMLDOC_COMPOSITE_TEXT} l_item then l_ppage.add_composite_text (l_comp) elseif {l_unavailable: XMLDOC_UNAVAILABLE} l_item then else check mismatch: False end end elseif {l_with_content: XMLDOC_WITH_CONTENT} l_parent_item then if {l_text_cont: XMLDOC_TEXT_CONTAINER} l_with_content then if l_text_cont.valid_item (l_item) then l_text_cont.add_item (l_item) else check False end end else l_with_content.add_item (l_item) end end end end end on_attribute (a_namespace: STRING; a_prefix: STRING; a_local_part: STRING; a_value: STRING) is -- Start of attribute. do --| should not be used ... in this xmldoc schema if a_local_part /= Void then if {l_output: XMLDOC_OUTPUT} output_switch then if a_local_part.is_case_insensitive_equal (att_output) then l_output.set_output (a_value) end elseif is_valid_output_scope and then last_item /= Void then if {l_title: XMLDOC_WITH_TITLE} last_item then if a_local_part.is_case_insensitive_equal (att_title) then l_title.set_title (a_value) end elseif {lst: XMLDOC_LIST} last_item then if a_local_part.is_case_insensitive_equal (att_ordered) then lst.set_ordered (a_value.is_case_insensitive_equal (value_true)) end end end end end on_start_tag_finish is -- End of start tag. do --| should not be used ... in this xmldoc schema end on_end_tag (a_namespace: STRING; a_prefix: STRING; a_local_part: STRING) is -- End tag. local l_item: like last_item l_content: like last_content l_id: INTEGER do l_id := tag_to_id (a_local_part) if is_valid_output_scope then l_content := last_content if l_content /= Void then remove_last_item end l_item := last_item if last_item = Void then --| most probably, there is a remaining empty text content check has_text_content: l_content /= Void end else remove_last_item if l_content = Void and {unused: XMLDOC_UNUSED} l_item then --| hack: to handle