| # API documentation code examples implemented, to check syntax |
| # and also expected effects. Only for code that is not already elsewhere, |
| # nor is too complex to set up. Some of those customization results |
| # are silly, just for the sake of checking. |
| |
| use strict; |
| |
| use utf8; |
| |
| # To check if there is no erroneous autovivification |
| #no autovivification qw(fetch delete exists store strict); |
| |
| use Texinfo::TreeElement; |
| |
| use Texinfo::Common; |
| use Texinfo::Convert::Texinfo; |
| use Texinfo::Convert::HTML; |
| |
| texinfo_set_from_init_file('MATHJAX_CONFIGURATION', |
| "options: { enableMenu: false }, |
| loader: { |
| load: [\'[tex]/physics\'], |
| versionWarnings: false |
| }, |
| tex: { |
| packages: {\'[+]\': [\'physics\']} |
| } |
| "); |
| texinfo_set_from_init_file('HTML_MATH', 'mathjax'); |
| |
| my $default_footnotestyle = texinfo_get_conf('footnotestyle'); |
| my $main_program_footnotestyle; |
| if (not defined($default_footnotestyle)) { |
| $main_program_footnotestyle = 'is undef'; |
| } elsif ($default_footnotestyle eq 'separate') { |
| $main_program_footnotestyle = 'is separate'; |
| } else { |
| $main_program_footnotestyle = 'not separate '.$default_footnotestyle; |
| } |
| |
| my %translations = ( |
| 'fr' => { |
| 'error-->' => {'' => 'erreur-->',}, |
| 'Higher' => {'Up direction button label' => 'Plus haut',}, |
| 'The @emph{Table of Contents}' => {'contents section heading' |
| => '@result{} La @emph{Table des mati@`eres}',}, |
| 'Forward' => {'Forward direction string' |
| => 'Vers l\'avant @result{}',}, |
| # ... |
| }, |
| 'de' => { |
| 'error-->' => {'' => 'Fehler-->',}, |
| # ... |
| }, |
| 'pl' => { |
| 'error-->' => {'' => 'błąd-->',}, |
| 'Higher' => {'Up direction button label' => 'Wyższy',}, |
| # ... |
| }, |
| # ... |
| ); |
| |
| texinfo_register_no_arg_command_formatting('-', undef, '­'); |
| |
| texinfo_register_no_arg_command_formatting('error', undef, undef, undef, |
| 'error-->'); |
| |
| texinfo_register_no_arg_command_texinfo('equiv', 'is the @strong{same} as'); |
| |
| $translations{'fr'}->{'is the @strong{same} as'} |
| = {'' => 'est la @strong{m@^eme} que',}; |
| |
| texinfo_register_style_command_formatting('sansserif', 'code', 'normal'); |
| texinfo_register_style_command_formatting('sansserif', 'code', 'preformatted'); |
| texinfo_style_command_set_quoting('sansserif', 0, 'normal'); |
| texinfo_style_command_set_quoting('sansserif', 1, 'preformatted'); |
| texinfo_register_upper_case_command('sc', 0); |
| texinfo_register_upper_case_command('var', 1); |
| |
| texinfo_register_accent_command_formatting('dotless', 'nodot', 'ij'); |
| |
| texinfo_register_direction_string_info('Up', 'button', undef, 'Higher'); |
| texinfo_register_direction_string_info('Forward', 'text', undef, |
| 'Forward'); |
| texinfo_register_special_unit_info('heading', 'contents', |
| 'The @emph{Table of Contents}'); |
| |
| texinfo_register_command_formatting('setchapternewpage', |
| Texinfo::Convert::HTML::default_command_conversion(undef, |
| 'documentlanguage')); |
| |
| texinfo_register_global_direction ('Appendix'); |
| texinfo_register_direction_string_info ('Appendix', 'text', undef, 'Appendix'); |
| |
| my $counter = 0; |
| |
| my $shown_styles; |
| my $footnotestyle; |
| my $footnotestyle_before_setting; |
| sub my_function_set_some_css { |
| my $converter = shift; |
| |
| $counter = 0; |
| |
| my $all_included_rules = $converter->css_get_info('rules'); |
| my $all_default_selectors = $converter->css_get_info('styles'); |
| my $titlefont_style = $converter->css_get_selector_style('h1.titlefont'); |
| $titlefont_style = 'undefined' if (!defined($titlefont_style)); |
| $shown_styles = $titlefont_style.' '. |
| $converter->css_get_selector_style('h1.shorttitlepage'); |
| $converter->css_set_selector_style('h1.titlefont', 'text-align:center'); |
| |
| # Need to set it only once, since it will be changed |
| if (!defined($footnotestyle_before_setting)) { |
| $footnotestyle_before_setting = $converter->get_conf('footnotestyle'); |
| $footnotestyle_before_setting = 'UNDEF' |
| if (not defined($footnotestyle_before_setting)); |
| } |
| $converter->set_conf('footnotestyle', 'separate'); |
| $footnotestyle = $main_program_footnotestyle |
| .'|'.$footnotestyle_before_setting |
| .'|'.$converter->get_conf('footnotestyle'); |
| # there should be nothing in @$all_included_rules for two reasons, |
| # first because it requires 'CSS_FILES' to be set to parseable |
| # CSS files, and CSS files parsing is done after the setup handler |
| # is called. |
| #print STDERR "all_included_rules: ".join('|', @$all_included_rules)."\n"; |
| |
| $converter->define_shared_conversion_state('quotation', 'color', |
| ['string', 'integer']); |
| $converter->set_shared_conversion_state('quotation', 'color', |
| 'special_black', 42); |
| |
| return 0; |
| } |
| |
| texinfo_register_handler('setup', \&my_function_set_some_css); |
| |
| my $buttons_done; |
| sub _set_appendix_direction_node_name { |
| my ($self, $document, $stage) = @_; |
| |
| my $sections_list = $document->sections_list(); |
| |
| if (!defined($sections_list) or !scalar(@{$sections_list})) { |
| return 0; |
| } |
| |
| foreach my $section_relations (@{$sections_list}) { |
| my $section = $section_relations->{'element'}; |
| if ($section->{'cmdname'} eq 'appendix') { |
| if (exists($section_relations->{'associated_node'})) { |
| my $node_relations = $section_relations->{'associated_node'}; |
| my $node = $node_relations->{'element'}; |
| my $label_element = Texinfo::Common::get_label_element($node); |
| if (defined($label_element)) { |
| my $node_name = Texinfo::Convert::Texinfo::convert_to_texinfo( |
| Texinfo::TreeElement::new( |
| {'contents' => $label_element->{'contents'}})); |
| $self->set_global_direction('Appendix', $node_name); |
| } |
| } |
| last; |
| } |
| } |
| |
| if (!$buttons_done) { |
| my $section_header_buttons_list |
| = $self->get_conf('SECTION_BUTTONS'); |
| my @modified_buttons = @$section_header_buttons_list; |
| push @modified_buttons, 'Appendix'; |
| $self->set_conf('SECTION_BUTTONS', \@modified_buttons); |
| |
| $buttons_done = 1; |
| } |
| |
| return 0; |
| } |
| |
| texinfo_register_handler('setup', |
| \&_set_appendix_direction_node_name); |
| |
| sub my_format_separate_anchor($$;$) { |
| my ($converter, $id, $class) = @_; |
| |
| return $converter->html_attribute_class('p', [$class])." id=\"$id\"></p>"; |
| } |
| |
| texinfo_register_formatting_function('format_separate_anchor', |
| \&my_format_separate_anchor); |
| |
| sub my_slanted_formatting_function { |
| my ($converter, $cmdname, $command, $args) = @_; |
| |
| my $text; |
| if (defined($args) and defined($args->[0])) { |
| $text = $args->[0]->{'normal'}; |
| } else { |
| # happens with bogus @-commands without argument, like @strong something |
| return ''; |
| } |
| |
| # @-command argument |
| my $element = $command->{'contents'}->[0]; |
| |
| # conversion in string context |
| my $result_string = $converter->convert_tree_new_formatting_context( |
| $element, 'in string', |
| $Texinfo::Convert::HTML::CTXF_string); |
| my $multi_flag = 0; |
| $multi_flag |= $Texinfo::Convert::HTML::CTXF_string; |
| $multi_flag |= $Texinfo::Convert::HTML::CTXF_code; |
| # conversion in code and string context |
| my $result_code_string |
| = $converter->convert_tree_new_formatting_context( |
| $element, 'in code string', $multi_flag); |
| |
| if ($converter->in_string()) { |
| return $result_string; |
| } |
| return "<i title=\"$result_string\">$text</i>\n" |
| . "<i title=\"$result_code_string\">again $text</i>\n"; |
| |
| # note that the result is already in code style because of the paragraph |
| # formatting customization |
| } |
| texinfo_register_command_formatting('slanted', \&my_slanted_formatting_function); |
| |
| sub my_email_formatting_function { |
| my ($converter, $cmdname, $command, $args) = @_; |
| |
| my $args_nr = 0; |
| if ($args) { |
| $args_nr = scalar(@$args); |
| } |
| |
| my $mail = ''; |
| my $mail_string = ''; |
| if ($args_nr > 0 and defined($args->[0])) { |
| my $mail_arg = $args->[0]; |
| $mail = $mail_arg->{'url'}; |
| $mail_string = $mail_arg->{'monospacestring'}; |
| } |
| |
| my $text = ''; |
| if ($args_nr > 1 and defined($args->[1]) |
| and defined($args->[1]->{'normal'})) { |
| my $text_arg = $args->[1]; |
| $text = $text_arg->{'normal'}; |
| } |
| $text = $mail_string unless ($text ne ''); |
| |
| my $tree = $converter->cdt('Generated @emph{@today{}} using ' |
| .'@uref{{homepage}, @emph{{program}}}.', |
| { 'homepage' => Texinfo::TreeElement::new( |
| { 'text' => $converter->get_conf('PACKAGE_URL') }), |
| 'program' => Texinfo::TreeElement::new( |
| { 'text' => $converter->get_conf('PROGRAM') }) }); |
| my $translated1 = $converter->convert_tree($tree); |
| |
| my $explanation_result; |
| if ($converter->in_string()) { |
| $explanation_result = $mail_string; |
| } else { |
| $explanation_result = $converter->html_attribute_class('a', ['myurl']) |
| .' href="'.$converter->url_protect_url_text($mail_string)."\">$text</a>"; |
| } |
| my $translated2 = $converter->convert_tree($converter->cdt( |
| '{explained_string} ({explanation})', |
| {'explained_string' => Texinfo::TreeElement::new({'type' => '_converted', |
| 'text' => $translated1}), |
| 'explanation' => Texinfo::TreeElement::new({'type' => '_converted', |
| 'text' => $explanation_result}) }), |
| "convert explained $cmdname"); |
| |
| $text .= " $translated2;"; |
| |
| my $result; |
| if ($converter->in_string()) { |
| return "$mail_string ($text) $shown_styles, $footnotestyle"; |
| } else { |
| $result = $converter->html_attribute_class('a', [$cmdname]) |
| ." href=\"mailto:$mail_string\">$text</a> [$shown_styles, $footnotestyle]"; |
| } |
| |
| if ($converter->in_preformatted_context()) { |
| my $pre_classes = $converter->preformatted_classes_stack(); |
| foreach my $pre_class (@$pre_classes) { |
| if ($Texinfo::Commands::preformatted_code_commands{$pre_class}) { |
| $result = '<var>' .$result. '</var>'; |
| last; |
| } |
| } |
| } |
| return $result; |
| } |
| |
| texinfo_register_command_formatting('email', \&my_email_formatting_function); |
| |
| sub _convert_math_command($$$$) { |
| my ($converter, $cmdname, $command, $args) = @_; |
| |
| my $arg; |
| if ($args and $args->[0]) { |
| $arg = $args->[0]->{'normal'}; |
| } else { |
| return ''; |
| } |
| |
| my $open = $converter->html_attribute_class('span', ['math-arg']); |
| my $arg_result = $open.'>'.$arg.'</span>' |
| if ($open ne ''); |
| my $result = $converter->html_attribute_class('em', [$cmdname, 'jax_p']) |
| . '>' . $arg_result . '</em>'; |
| |
| return $result; |
| } |
| |
| texinfo_register_command_formatting('math', \&_convert_math_command); |
| |
| # put here as it is in the documentation, but not used as the |
| # final version is used, below. |
| sub my_tree_element_convert_paragraph_type($$$$) { |
| my ($converter, $type, $element, $content) = @_; |
| |
| $content = '' if (!defined($content)); |
| |
| if ($converter->in_string()) { |
| return $content; |
| } |
| |
| my @contents = @{$element->{'contents'}}; |
| push @contents, Texinfo::TreeElement::new({'text' => ' HTML text '}); |
| my $new_element = Texinfo::TreeElement::new({'contents' => \@contents}); |
| my $result = $converter->convert_tree_in_code_context($new_element); |
| return "<p>".$result."</p>"; |
| } |
| |
| |
| sub my_final_convert_paragraph_type($$$$) { |
| my ($converter, $type, $element, $content) = @_; |
| |
| $content = '' if (!defined($content)); |
| |
| my $prepended |
| = $converter->get_associated_formatted_inline_content($element); |
| if ($converter->in_string()) { |
| return $prepended.$content; |
| } |
| |
| my @contents = @{$element->{'contents'}}; |
| push @contents, Texinfo::TreeElement::new({'text' => ' HTML text '}); |
| my $new_element = Texinfo::TreeElement::new({'contents' => \@contents}); |
| my $result = $converter->convert_tree_in_code_context($new_element); |
| return "<p>".$prepended.$result."</p>"; |
| } |
| |
| texinfo_register_type_formatting('paragraph', |
| \&my_final_convert_paragraph_type); |
| |
| sub my_test_documentation_convert_indented_command($$$$$) { |
| my ($converter, $cmdname, $command, $args, $content) = @_; |
| |
| if (!defined($content) or $content eq '') { |
| return ''; |
| } |
| |
| if ($converter->in_string()) { |
| return $content; |
| } |
| |
| my $non_breaking_space = $converter->get_info('non_breaking_space'); |
| my $result = '<tr><td>' .$non_breaking_space. '</tr></td>'; |
| |
| return $converter->html_attribute_class('table', [$cmdname]).'>' |
| . $result . $content . "</td></tr></table>\n"; |
| } |
| |
| texinfo_register_command_formatting('indentedblock', |
| \&my_test_documentation_convert_indented_command); |
| |
| sub my_test_documentation_convert_index_entry_command_type($$$$) { |
| my ($converter, $type, $element, $content) = @_; |
| |
| if ($converter->multi_expanded_region() |
| or $converter->in_string()) { |
| return ''; |
| } |
| |
| my $cmdname = $element->{'cmdname'}; |
| |
| my $color_number = $converter->get_shared_conversion_state('quotation', |
| 'color', 'purple1'); |
| my $color2_number = $converter->get_shared_conversion_state('quotation', |
| 'color', 'special_black'); |
| $color_number++; |
| $converter->set_shared_conversion_state('quotation', |
| 'color', 'purple1', $color_number); |
| |
| my $index_id = $converter->command_id($element); |
| if (defined($index_id) and $index_id ne '') { |
| my $result = '<table>'; |
| $counter++; |
| my $anchor_id = 'anchor_id_' . $counter; |
| my $anchor_with_counter |
| = &{$converter->formatting_function('format_separate_anchor')}( |
| $converter, $anchor_id, 'myanchor_class'); |
| $result .= $anchor_with_counter; |
| $result .= "\n" unless ($converter->in_preformatted_context()); |
| |
| my $target_element = $element; |
| my $target_text = $converter->command_text($target_element) |
| . "<code>purple: $color_number, black: $color2_number</code>"; |
| my $target_href = $converter->command_href($target_element); |
| my $hyperlink = "<a href=\"$target_href\">$target_text</a>"; |
| |
| my $entry_root_link = ''; |
| my $associated_command |
| = $converter->command_root_element_command($target_element); |
| if (defined($associated_command)) { |
| my $associated_command_href |
| = $converter->command_href($associated_command); |
| my $associated_command_text |
| = $converter->command_text($associated_command); |
| |
| if (defined($associated_command_href)) { |
| $entry_root_link |
| = "<a href=\"$associated_command_href\">" |
| ."$associated_command_text</a>"; |
| } elsif (defined($associated_command_text)) { |
| $entry_root_link = $associated_command_text; |
| } |
| } |
| |
| my $formatted_entry = "<td><tr>$hyperlink</tr>" |
| ."<tr>$entry_root_link</tr></td>\n"; |
| |
| my $label_element = $target_element->{'contents'}->[0]; |
| Texinfo::Convert::Text::set_options_code( |
| $converter->{'convert_text_options'}); |
| Texinfo::Convert::Text::set_options_encoding_if_not_ascii($converter, |
| $converter->{'convert_text_options'}); |
| my $file_name = Texinfo::Convert::Text::convert_to_text($label_element, |
| $converter->{'convert_text_options'}); |
| Texinfo::Convert::Text::reset_options_code( |
| $converter->{'convert_text_options'}); |
| Texinfo::Convert::Text::reset_options_encoding( |
| $converter->{'convert_text_options'}); |
| |
| $result .= $formatted_entry . "<td><tr>$file_name</tr></td>\n"; |
| $result .= "</table>\n"; |
| return $result; |
| } else { |
| my $text_element = {'text' => '@'.$cmdname}; |
| my $tree = $converter->cdt('No value for @strong{{item}}', |
| {'item' => $text_element}); |
| my $no_value_converted_output = $converter->convert_tree($tree); |
| return "<div>$no_value_converted_output</div>\n"; |
| } |
| |
| return ''; |
| } |
| |
| texinfo_register_type_formatting('index_entry_command', |
| \&my_test_documentation_convert_index_entry_command_type); |
| |
| sub my_test_documentation_convert_xref_commands($$$$) { |
| my ($converter, $cmdname, $command, $args) = @_; |
| |
| my $xref_tree_element = $command; |
| my $prepended = ''; |
| |
| my $arg_node = $xref_tree_element->{'contents'}->[0]; |
| if ($arg_node and $arg_node->{'extra'} |
| and defined($arg_node->{'extra'}->{'normalized'})) { |
| my $target_node |
| = $converter->converter_find_identifier_target( |
| $arg_node->{'extra'}->{'normalized'}); |
| my $identifier = $converter->command_id($target_node); |
| $prepended = "<samp>$identifier</samp>"; |
| } |
| |
| return $prepended |
| . &{$converter->default_command_conversion($cmdname)}($converter, |
| $cmdname, $command, $args); |
| } |
| |
| texinfo_register_command_formatting('xref', |
| \&my_test_documentation_convert_xref_commands); |
| |
| |
| sub my_test_documentation_convert_printindex_command($$$$) { |
| my ($converter, $cmdname, $command, $args) = @_; |
| |
| my $printindex_element = $command; |
| my $prepended = ''; |
| |
| my ($output_unit, $root_command) |
| = $converter->get_element_root_command_element($printindex_element); |
| my $index_element_id = $converter->command_id($root_command); |
| $prepended = "<strong>RC: $index_element_id</strong>"; |
| |
| return $prepended |
| . &{$converter->default_command_conversion($cmdname)}($converter, |
| $cmdname, $command, $args); |
| } |
| |
| texinfo_register_command_formatting('printindex', |
| \&my_test_documentation_convert_printindex_command); |
| |
| |
| sub my_node_file_name($$$) { |
| my ($converter, $element, $filename) = @_; |
| |
| # .... |
| my $node_file_name = 'prepended_to_filenames-'.$filename; |
| return $node_file_name; |
| } |
| |
| texinfo_register_file_id_setting_function('node_file_name', |
| \&my_node_file_name); |
| |
| |
| sub my_label_target_name($$$$) { |
| my ($converter, $normalized, $label_element, $default_target) = @_; |
| |
| if (defined($normalized)) { |
| my $element = $converter->converter_find_identifier_target($normalized); |
| return 'prepended_to_labels-'.$element->{'extra'}->{'identifier'}; |
| } |
| return $default_target; |
| } |
| |
| texinfo_register_file_id_setting_function('label_target_name', |
| \&my_label_target_name); |
| |
| sub my_format_translate_message($$$;$) { |
| my ($converter, $string, $lang, $translation_context) = @_; |
| |
| return $string if (!defined($lang) or $lang eq ''); |
| $translation_context = '' if (!defined($translation_context)); |
| if (exists($translations{$lang}) |
| and exists($translations{$lang}->{$string}) |
| and exists($translations{$lang}->{$string}->{$translation_context})) { |
| my $translation = $translations{$lang}->{$string}->{$translation_context}; |
| return $translation; |
| } |
| return undef; |
| } |
| |
| texinfo_register_formatting_function('format_translate_message', |
| \&my_format_translate_message); |
| |
| 1; |