docbook.pm 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574
  1. #+##############################################################################
  2. #
  3. # docbook.pm: convert to docbook
  4. #
  5. # Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 3 of the License,
  10. # or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. # Originally written by Patrice Dumas.
  21. #
  22. #-##############################################################################
  23. # regarding sections and nodes, in docbook we don't care at all about the
  24. # splitting done in the main program. When there is a node, it is recorded as
  25. # being pending. When there is a section it is opened, and closed when
  26. # there is the next section or end of file.
  27. use strict;
  28. my %docbook_complex_format;
  29. my $kept_footnote_function;
  30. my $docbook_in_footnote;
  31. my %docbook_sections;
  32. my %def_format_docbook;
  33. my %def_argument_types_docbook;
  34. my $docbook_pending_node_id;
  35. my $docbook_current_section;
  36. my @docbook_multitable_stack = ();
  37. my @docbook_table_stack = ();
  38. my @docbook_special_quotation;
  39. sub docbook_default_load(;$)
  40. {
  41. my $from_command_line = shift;
  42. t2h_default_set_variables_xml();
  43. set_default('DOCTYPE', '<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
  44. <!ENTITY tex "TeX">
  45. <!ENTITY latex "LaTeX">
  46. ]>');
  47. @T2H_FORMAT_EXPAND = ('docbook');
  48. @IMAGE_EXTENSIONS = ('eps', 'gif', 'jpg', 'jpeg', 'pdf', 'png', 'svg', 'txt');
  49. set_default('INLINE_INSERTCOPYING', 1);
  50. # this should lead to end_section being only called at the end of sectioning
  51. set_default('USE_NODES', 0);
  52. set_default('USE_SECTIONS', 1);
  53. set_default('SHOW_MENU', 0);
  54. set_default('SHOW_TITLE', 0);
  55. set_default('HEADERS', 0);
  56. set_default('SPLIT', '');
  57. # certainly irrelevant
  58. set_default('SIMPLE_MENU', 0);
  59. t2h_default_push_handler(\&docbook_initialize_variables, \@command_handler_init);
  60. %style_map = ();
  61. t2h_default_copy_style_map (\%default_style_map, \%style_map);
  62. foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents))
  63. {
  64. $style_map{$accent_command} = { 'function' => \&xml_default_accent };
  65. }
  66. delete $style_map{'sc'}->{'inline_attribute'};
  67. # FIXME there is a code element in v4.3
  68. $style_map{'code'}->{'inline_attribute'} = 'literal';
  69. $style_map{'strong'}->{'inline_attribute'} = 'emphasis role="bold"';
  70. $style_map{'kbd'}->{'inline_attribute'} = 'userinput';
  71. $style_map{'w'}->{'end'} = '<!-- /@w -->';
  72. $style_map{'='}->{'function'} = \&docbook_macron;
  73. $style_map{'b'}->{'inline_attribute'} = 'emphasis role="bold"';
  74. $style_map{'cite'}->{'inline_attribute'} = 'citetitle';
  75. $style_map{'command'}->{'inline_attribute'} = 'command';
  76. $style_map{'dfn'}->{'inline_attribute'} = 'firstterm';
  77. $style_map{'emph'}->{'inline_attribute'} = 'emphasis';
  78. $style_map{'env'}->{'inline_attribute'} = 'envar';
  79. $style_map{'file'}->{'inline_attribute'} = 'filename';
  80. $style_map{'i'}->{'inline_attribute'} = 'wordasword';
  81. $style_map{'key'}->{'inline_attribute'} = 'keycap';
  82. delete $style_map{'key'}->{'begin'};
  83. delete $style_map{'key'}->{'end'};
  84. $style_map{'option'}->{'inline_attribute'} = 'option';
  85. $style_map{'t'}->{'inline_attribute'} = 'literal';
  86. delete $style_map{'sansserif'}->{'inline_attribute'};
  87. delete $style_map{'r'}->{'inline_attribute'};
  88. $style_map{'indicateurl'}->{'inline_attribute'} = 'wordasword';
  89. delete $style_map{'indicateurl'}->{'begin'};
  90. delete $style_map{'indicateurl'}->{'end'};
  91. $style_map{'var'}->{'inline_attribute'} = 'replaceable';
  92. delete $style_map{'verb'}->{'inline_attribute'};
  93. $style_map{'email'}->{'function'} = \&docbook_email;
  94. $style_map{'math'}->{'function'} = \&docbook_math;
  95. $style_map{'uref'}->{'function'} = \&docbook_uref;
  96. $style_map{'url'}->{'function'} = \&docbook_uref;
  97. $style_map{'titlefont'}->{'function'} = \&docbook_titlefont;
  98. #$style_map{'samp'}->{'function'} = \&docbook_samp;
  99. #delete $style_map{'samp'}->{'inline_attribute'};
  100. $style_map{'samp'}->{'inline_attribute'} = 'literal';
  101. $style_map{'samp'}->{'begin'} = '&lsquo;';
  102. $style_map{'samp'}->{'end'} = '&rsquo;';
  103. $kept_footnote_function = $style_map{'footnote'}->{'function'};
  104. $style_map{'footnote'}->{'function'} = \&docbook_footnote;
  105. foreach my $style (keys(%style_map))
  106. {
  107. delete ($style_map{$style}->{'quote'});
  108. }
  109. #use Data::Dumper;
  110. %style_map_pre = ();
  111. t2h_default_copy_style_map (\%style_map, \%style_map_pre);
  112. $style_map_pre{'r'}->{'inline_attribute'} = 'lineannotation';
  113. $colon_command_punctuation_characters{'.'} = '&period;';
  114. $colon_command_punctuation_characters{':'} = '&colon;';
  115. $colon_command_punctuation_characters{'?'} = '&quest;';
  116. $colon_command_punctuation_characters{'!'} = '&excl;';
  117. $stop_paragraph_command{'titlefont'} = 0;
  118. # FIXME
  119. #$no_paragraph_commands{'anchor'} = 0;
  120. # FIXME
  121. delete $special_accents{'ringaccent'};
  122. $special_accents{'ogonek'} = 'aeiuAEIU';
  123. %simple_map = %default_simple_map;
  124. %simple_map_pre = %simple_map;
  125. # FIXME right? &lstrok; &Lstrok;
  126. $things_map{'l'} = '/l';
  127. $things_map{'L'} = '/L';
  128. $things_map{'TeX'} = '&tex;';
  129. $things_map{'LaTeX'} = '&latex;';
  130. $things_map{'enddots'} = '&hellip;.';
  131. $things_map{'minus'} = '&minus;';
  132. # FIXME &lowast;
  133. $things_map{'point'} = '-!-';
  134. # FIXME &equiv;
  135. $things_map{'equiv'} = '==';
  136. # FIXME no &lsaquo; nor &rsaquo;
  137. $things_map{'guilsinglright'} = '&gt;';
  138. $things_map{'guilsinglleft'} = '&lt;';
  139. # The following is unneeded because normal_text is redefined.
  140. # FIXME it should certainly be better to leave those substitutions,
  141. # or even hardcodes them in normal_text.
  142. # t2h_remove_text_substitutions("'", 1, 0, 0, 1);
  143. # t2h_remove_text_substitutions('`', 1, 0, 0, 1);
  144. $things_map{'quotedblbase'} = '&ldquor;';
  145. $things_map{'quotesinglbase'} = '&lsquor;';
  146. %pre_map = %things_map;
  147. #delete $inter_item_commands{'cindex'};
  148. #$no_paragraph_commands{'cindex'} = 0;
  149. $no_paragraph_commands{'float'} = 0;
  150. %docbook_complex_format = (
  151. 'example' => 'screen',
  152. 'smallexample' => 'screen',
  153. 'display' => 'literallayout',
  154. 'smalldisplay' => 'literallayout',
  155. 'lisp' => 'programlisting',
  156. 'smalllisp' => 'programlisting',
  157. 'format' => 'abstract',
  158. 'smallformat' => 'screen'
  159. );
  160. %docbook_sections = (
  161. 'top' => 'chapter',
  162. 'part' => 'part',
  163. 'chapter' => 'chapter',
  164. 'unnumbered' => 'chapter',
  165. 'centerchap' => 'chapter',
  166. 'appendix' => 'appendix',
  167. 'majorheading' => 'other',
  168. 'chapheading' => 'other',
  169. 'heading' => 'sect1',
  170. 'subheading' => 'sect2',
  171. 'subsubheading' => 'sect3',
  172. 2 => 'sect1',
  173. 3 => 'sect2',
  174. 4 => 'sect3'
  175. );
  176. %def_format_docbook = (
  177. 'deffn' => [ ['function', 'name'] ],
  178. 'defvr' => [ ['varname', 'name'] ],
  179. 'deftypefn' => [ [ 'returnvalue', 'type' ], ['function', 'name'] ],
  180. 'deftypeop' => [ ['returnvalue', 'type'], ['methodname', 'name'] ],
  181. 'deftypevr' => [ ['returnvalue', 'type'], ['varname', 'name'] ],
  182. 'defcv' => [ ['classname', 'class'], ['property', 'name'] ],
  183. 'deftypecv' => [ ['returnvalue', 'type'], ['property', 'name'] ],
  184. 'defop' => [ ['classname', 'class'], ['methodname', 'name'] ],
  185. 'deftp' => [ ['structname', 'name'] ]
  186. );
  187. %def_argument_types_docbook = (
  188. 'param' => 'replaceable',
  189. 'paramtype' => 'type',
  190. 'delimiter' => ''
  191. );
  192. @docbook_special_quotation = ('note', 'caution', 'important', 'tip', 'warning');
  193. $region_formats_kept{'copying'} = 1;
  194. %format_map = (
  195. 'group' => '',
  196. 'raggedright' => '',
  197. 'copying' => 'copying',
  198. );
  199. $print_Top = \&docbook_print_Top;
  200. $print_Top_footer = \&docbook_print_Top_footer;
  201. $print_page_head = \&docbook_print_page_head;
  202. $print_foot_navigation = \&docbook_noop;
  203. $contents = \&docbook_noop;
  204. $shortcontents = \&docbook_noop;
  205. $about_body = \&docbook_noop;
  206. $print_page_foot = \&docbook_print_page_foot;
  207. $end_section = \&docbook_end_section;
  208. $one_section = \&docbook_one_section;
  209. $acronym_like = \&docbook_acronym_like;
  210. $anchor_label = \&docbook_anchor_label;
  211. $begin_format_texi = \&docbook_begin_format_texi;
  212. $cartouche = \&docbook_cartouche;
  213. $cell = \&docbook_cell;
  214. $complex_format = \&docbook_complex_format;
  215. $def = \&docbook_def;
  216. $def_line = \&docbook_def_line;
  217. $def_item = \&docbook_def_item;
  218. $element_label = \&docbook_element_label;
  219. $external_ref = \&docbook_external_ref;
  220. $float = \&docbook_float;
  221. $foot_line_and_ref = \&docbook_foot_line_and_ref;
  222. $format = \&docbook_format;
  223. $format_list_item_texi = \&docbook_format_list_item_texi;
  224. $heading = \&docbook_heading;
  225. $image = \&docbook_image;
  226. $image_files = \&docbook_image_files;
  227. $index_entry_command = \&docbook_index_entry_command;
  228. $index_entry_label = \&docbook_index_entry_label;
  229. $index_summary = \&docbook_index_summary;
  230. $internal_ref = \&docbook_internal_ref;
  231. $insertcopying = \&docbook_insertcopying;
  232. $list_item = \&docbook_list_item;
  233. $misc_element_label = \&docbook_noop;
  234. $normal_text = \&docbook_normal_text;
  235. $paragraph = \&docbook_paragraph;
  236. $preformatted = \&docbook_preformatted;
  237. $printindex = \&docbook_printindex;
  238. $protect_text = \&xml_default_protect_text;
  239. $quotation = \&docbook_quotation;
  240. $quotation_prepend_text = \&docbook_quotation_prepend_text;
  241. $listoffloats = \&docbook_noop;
  242. $raw = \&docbook_raw;
  243. $row = \&docbook_row;
  244. $sp = \&docbook_sp;
  245. $style = \&docbook_style;
  246. $table_item = \&docbook_table_item;
  247. $table_line = \&docbook_table_line;
  248. $table_list = \&docbook_table_list;
  249. $misc_command_line = \&docbook_misc_commands;
  250. }
  251. sub docbook_footnote
  252. {
  253. $docbook_in_footnote = 1;
  254. my $result = &$kept_footnote_function(@_);
  255. $docbook_in_footnote = 0;
  256. return $result;
  257. }
  258. sub docbook_macron($$)
  259. {
  260. my $accent = shift;
  261. my $args = shift;
  262. return $args->[0] . "&macr;";
  263. }
  264. sub docbook_samp($$)
  265. {
  266. shift;
  267. my $args = shift;
  268. return "&lsquo;<literal>$args->[0]</literal>&rsquo;";
  269. }
  270. sub docbook_email($$)
  271. {
  272. my $command = shift;
  273. my $args = shift;
  274. my $mail = shift @$args;
  275. my $text = shift @$args;
  276. $mail = main::normalise_space($mail);
  277. if (defined($text) and $text =~ /\S/)
  278. {
  279. # FIXME normalise_space would be more legible.
  280. #return docbook_add_id('ulink').' url="mailto:'.$mail.'">'.main::normalise_space($text).'</ulink>';
  281. return docbook_add_id('ulink').' url="mailto:'.$mail.'">'.$text.'</ulink>';
  282. }
  283. return docbook_add_id('email').">$mail</email>";
  284. }
  285. sub docbook_uref($$)
  286. {
  287. shift;
  288. my $args = shift;
  289. my $url = shift @$args;
  290. my $text = shift @$args;
  291. my $replacement = shift @$args;
  292. $url = main::normalise_space($url);
  293. $text = '' if (!defined($text));
  294. $replacement = '' if (!defined($replacement));
  295. $replacement = $text if ($replacement eq '');
  296. $replacement = $url if ($replacement eq '');
  297. $replacement = main::normalise_space($replacement);
  298. return docbook_add_id('ulink')." url=\"$url\">$replacement</ulink>";
  299. }
  300. # FIXME
  301. sub docbook_titlefont($$)
  302. {
  303. shift;
  304. my $args = shift;
  305. return "$args->[0]";
  306. }
  307. # FIXME there ought to be something better... Like use tex4ht mathml
  308. # output or something like that
  309. sub docbook_math($$)
  310. {
  311. shift;
  312. my $args = shift;
  313. my $text = shift @$args;
  314. return $text;
  315. }
  316. sub docbook_print_page_head($)
  317. {
  318. my $fh = shift;
  319. my $language = get_conf('documentlanguage');
  320. my $doctype = get_conf('DOCTYPE');
  321. my $extension = get_conf('EXTENSION');
  322. print $fh <<EOT;
  323. <?xml version="1.0"?>
  324. $doctype
  325. <book id="$Texi2HTML::THISDOC{'file_base_name'}.$extension" lang="$language">
  326. EOT
  327. }
  328. sub docbook_print_page_foot($)
  329. {
  330. my $fh = shift;
  331. print $fh "". docbook_close_section();
  332. print $fh <<EOT;
  333. </book>
  334. EOT
  335. }
  336. sub docbook_print_Top($$$)
  337. {
  338. my $fh = shift;
  339. my $has_top_heading = shift;
  340. my $element = shift;
  341. main::print_lines($fh, $Texi2HTML::THIS_SECTION);
  342. }
  343. sub docbook_element_tag($)
  344. {
  345. my $element = shift;
  346. #print STDERR "$element->{'texi'}, $element->{'tag_level'}, $element->{'level'}\n";
  347. return $docbook_sections{$element->{'tag_level'}} if (exists($docbook_sections{$element->{'tag_level'}}));
  348. return $docbook_sections{$element->{'level'}} if (exists($docbook_sections{$element->{'level'}}));
  349. }
  350. sub docbook_node_id($)
  351. {
  352. my $node_texi = shift;
  353. my $node = main::substitute_line($node_texi, 'docbook node id', {'code_style' => 1, 'remove_texi' => 1});
  354. $node =~ s/[\s\"]/-/g;
  355. return &$protect_text($node);
  356. }
  357. sub docbook_initialize_variables()
  358. {
  359. $docbook_pending_node_id = undef;
  360. $docbook_current_section = undef;
  361. @docbook_multitable_stack = ();
  362. @docbook_table_stack = ();
  363. }
  364. sub docbook_add_id($)
  365. {
  366. my $element = shift;
  367. my $result = "<$element";
  368. if (defined($docbook_pending_node_id) and (!$docbook_in_footnote or $element eq 'footnote'))
  369. {
  370. $result .= " id=\"$docbook_pending_node_id\"";
  371. $docbook_pending_node_id = undef;
  372. }
  373. return $result;
  374. }
  375. sub docbook_heading($$$$$)
  376. {
  377. my $element = shift;
  378. my $command = shift;
  379. my $texi_line = shift;
  380. my $line = shift;
  381. my $in_preformatted = shift;
  382. if (defined($command) and $command =~ /heading/)
  383. {
  384. my $text = '';
  385. if (defined($line))
  386. {
  387. $text = $line;
  388. # this isn't done in main program in that case...
  389. chomp ($text);
  390. $text =~ s/^\s*//;
  391. }
  392. return docbook_add_id('bridgehead')." renderas=\"$docbook_sections{$command}\">$text</bridgehead>\n";
  393. }
  394. my $result = '';
  395. # FIXME verify xreflabel
  396. if ($command ne 'node')
  397. {
  398. # close previous section
  399. $result .= docbook_close_section();
  400. my $title = $element->{'text_nonumber'};
  401. my $label = '';
  402. my $xreflabel = '';
  403. if ($element->{'number'})
  404. {
  405. my $label_nr = $element->{'number'};
  406. #$label_nr =~ s/\.$//;
  407. $label = $label_nr;
  408. }
  409. else
  410. {
  411. my $xreftitle = $title;
  412. $xreflabel = " xreflabel=\"$xreftitle\"";
  413. }
  414. $result .= docbook_add_id(docbook_element_tag($element) . " label=\"${label}\"${xreflabel}");
  415. $result .= ">\n<title>$title</title>\n";
  416. $docbook_current_section = $element;
  417. }
  418. return $result;
  419. }
  420. sub docbook_element_label($$$$)
  421. {
  422. my $id = shift;
  423. my $element = shift;
  424. my $command = shift;
  425. my $line = shift;
  426. if ($command eq 'node')
  427. {
  428. $docbook_pending_node_id = docbook_node_id($element->{'texi'});
  429. }
  430. return '';
  431. }
  432. sub docbook_paragraph($$$$$$$$$$$$)
  433. {
  434. my $text = shift;
  435. my $align = shift;
  436. my $indent = shift;
  437. my $paragraph_command = shift;
  438. my $paragraph_command_formatted = shift;
  439. my $paragraph_number = shift;
  440. my $format = shift;
  441. my $item_nr = shift;
  442. my $enumerate_style = shift;
  443. my $number = shift;
  444. my $command_stack_at_end = shift;
  445. my $command_stack_at_begin = shift;
  446. if (defined($paragraph_number) and defined($$paragraph_number))
  447. {
  448. $$paragraph_number++;
  449. }
  450. # no para in multitables, caption and shortcaptions.
  451. my $top_stack = '';
  452. $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin));
  453. return $text if ($top_stack eq 'multitable' or $top_stack eq 'shortcaption' or $top_stack eq 'caption' or $top_stack eq 'documentdescription');
  454. if ($text =~ /\S/)
  455. {
  456. #return docbook_add_id('para').">$text</para>";
  457. return "<para>$text</para>";
  458. }
  459. return $text;
  460. }
  461. sub docbook_def_line($$$$$$$$$$$$$$$)
  462. {
  463. my $category_prepared = shift;
  464. my $name = shift;
  465. my $type = shift;
  466. my $arguments = shift;
  467. my $index_label = shift;
  468. my $arguments_array = shift;
  469. my $arguments_type_array = shift;
  470. my $unformatted_arguments_array = shift;
  471. my $command = shift;
  472. my $class_name = shift;
  473. my $category = shift;
  474. my $class = shift;
  475. my $style = shift;
  476. my $original_command = shift;
  477. my %unformatted_arguments = ();
  478. my @unformatted_args = @$unformatted_arguments_array;
  479. foreach my $type (@$arguments_type_array)
  480. {
  481. my $unformatted_arg = shift @unformatted_args;
  482. $unformatted_arguments{$type} = $unformatted_arg;
  483. }
  484. # FIXME unformatted!
  485. my $result = "<synopsis role=\"$unformatted_arguments{'category'}\"><indexterm role=\""
  486. .$main::index_prefix_to_name{$style}."\"><primary>$class_name</primary></indexterm>";
  487. my %arguments = ( 'prepared_category' => $category_prepared,
  488. 'category' => $category,
  489. 'name' => $name,
  490. 'type' => $type,
  491. 'class' => $class
  492. );
  493. foreach my $type (keys(%arguments))
  494. {
  495. $arguments{$type} = '' if (!defined($arguments{$type}));
  496. }
  497. foreach my $mandatory_arg (@{$def_format_docbook{$command}})
  498. {
  499. my $elem = $mandatory_arg->[0];
  500. #if ($elem eq 'returnvalue' and $unformatted_arguments{$mandatory_arg->[1]} =~ /^\s*\@code\{/)
  501. if ($elem eq 'returnvalue' and $unformatted_arguments{$mandatory_arg->[1]} =~ /\@code\{/)
  502. {
  503. # FIXME unformatted
  504. my $arg_without_at_command = $unformatted_arguments{$mandatory_arg->[1]};
  505. #$arg_without_at_command =~ s/\s*\@code\{//;
  506. #$arg_without_at_command =~ s/\}\s*$//;
  507. while ($arg_without_at_command =~ /\@code\{([^\{\}]*)\}/)
  508. {
  509. $arg_without_at_command =~ s/\@code\{([^\{\}]*)\}/$1/;
  510. }
  511. $result .= "<$elem>$arg_without_at_command</$elem>";
  512. }
  513. else
  514. {
  515. $result .= "<$elem>$arguments{$mandatory_arg->[1]}</$elem>";
  516. }
  517. }
  518. my @types = @$arguments_type_array;
  519. @unformatted_args = @$unformatted_arguments_array;
  520. foreach my $arg (@$arguments_array)
  521. {
  522. my $type = shift @types;
  523. my $unformatted = shift @unformatted_args;
  524. if (exists ($def_argument_types_docbook{$type}))
  525. {
  526. if ($def_argument_types_docbook{$type} and
  527. ($type eq 'paramtype' or ($unformatted !~ /^\s*\@var\{/)))
  528. {
  529. $result .= "<$def_argument_types_docbook{$type}>$arg</$def_argument_types_docbook{$type}>";
  530. }
  531. else
  532. {
  533. $result .= $arg;
  534. }
  535. }
  536. }
  537. $result .= "</synopsis>\n";
  538. return $result;
  539. }
  540. # FIXME
  541. # @deffn
  542. # @c comment
  543. # @end deffn
  544. # leads to the creation of a <definitionitem> with a comment within,
  545. # while there should be no definitionitem
  546. sub docbook_def_item($)
  547. {
  548. my $text = shift;
  549. my $only_inter_item_commands = shift;
  550. if ($text =~ /\S/)
  551. {
  552. return '<blockquote>' . $text . '</blockquote>' unless $only_inter_item_commands;
  553. return $text;
  554. }
  555. return '';
  556. }
  557. sub docbook_def($)
  558. {
  559. my $text = shift;
  560. return docbook_add_id('informalfigure').'>'.$text.'</informalfigure>';
  561. }
  562. sub docbook_preformatted($$$$$$$$$$$$)
  563. {
  564. my $text = shift;
  565. my $pre_style = shift;
  566. my $class = shift;
  567. my $leading_command = shift;
  568. my $leading_command_formatted = shift;
  569. my $preformatted_number = shift;
  570. my $format = shift;
  571. my $item_nr = shift;
  572. my $enumerate_style = shift;
  573. my $number = shift;
  574. my $command_stack_at_end = shift;
  575. my $command_stack_at_begin = shift;
  576. return $text;
  577. }
  578. sub docbook_misc_commands($$$$$)
  579. {
  580. my $macro = shift;
  581. my $line = shift;
  582. my $args = shift;
  583. my $stack = shift;
  584. my $state = shift;
  585. #print STDERR "$macro $line";
  586. #print STDERR "ARGS @$args\n" if defined ($args);
  587. #my $result_text = undef;
  588. my $result_text = undef;
  589. if ($macro eq 'c' or $macro eq 'comment' and scalar(@$args))
  590. {
  591. my $comment_line = $args->[0];
  592. chomp ($comment_line);
  593. # makeinfo remove all the leading spaces
  594. $comment_line =~ s/^\s//;
  595. $result_text = &$comment ($comment_line);
  596. }
  597. elsif ($macro eq 'settitle')
  598. {
  599. # FIXME to be formatted? Also maybe in line_command. And in html, it
  600. # is handled by heading _text
  601. my $arg = $args->[0];
  602. $arg =~ s/^\s*//;
  603. chomp($arg);
  604. $result_text = "<title>$arg</title>\n";
  605. }
  606. return ($macro, $line, $result_text);
  607. }
  608. sub docbook_foot_line_and_ref($$$$$$$)
  609. {
  610. my $number_in_doc = shift;
  611. my $number_in_page = shift;
  612. my $footnote_id = shift;
  613. my $place_id = shift;
  614. my $document_file = shift;
  615. my $footnote_file = shift;
  616. my $lines = shift;
  617. my $state = shift;
  618. my $result = docbook_add_id('footnote').'>';
  619. foreach my $line (@$lines)
  620. {
  621. $result .= $line;
  622. }
  623. return ([], $result . '</footnote>');
  624. }
  625. sub docbook_any_ref($$$)
  626. {
  627. my $type = shift;
  628. my $args = shift;
  629. my $unformatted_args = shift;
  630. # FIXME?
  631. if ($type eq 'inforef')
  632. {
  633. my $node_file = "($args->[2])$args->[0]";
  634. if ($args->[1] ne '')
  635. {
  636. return "*note $args->[1]: $node_file";
  637. }
  638. else
  639. {
  640. return "*note ${node_file}::";
  641. }
  642. }
  643. else
  644. {
  645. if (($args->[3] ne '') or ($args->[4] ne ''))
  646. {
  647. return '' if ($args->[4] eq '');
  648. my $section_name = $args->[2];
  649. $section_name = $args->[0] if ($section_name eq '');
  650. if ($type eq 'ref')
  651. {
  652. return gdt('section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', { 'section_name' => $section_name, 'book' => $args->[4] },{'duplicate'=>1});
  653. }
  654. elsif ($type eq 'xref')
  655. {
  656. return gdt('See section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', { 'section_name' => $section_name, 'book' => $args->[4] },{'duplicate'=>1});
  657. }
  658. elsif ($type eq 'pxref')
  659. {
  660. return gdt('see section `@asis{}`{section_name}\'@asis{}\' in @cite{{book}}', { 'section_name' => $section_name, 'book' => $args->[4] },{'duplicate'=>1});
  661. }
  662. }
  663. my $link = docbook_node_id($unformatted_args->[0]);
  664. my $title = $args->[2];
  665. $title = $args->[1] if ($title eq '');
  666. if ($title eq '')
  667. {
  668. if ($type eq 'ref')
  669. {
  670. return gdt('{ref}', {'ref' => docbook_add_id('xref')." linkend=\"$link\"></xref>"});
  671. }
  672. elsif ($type eq 'pxref')
  673. {
  674. return gdt('see {ref}', {'ref' => docbook_add_id('xref')." linkend=\"$link\"></xref>"});
  675. }
  676. elsif ($type eq 'xref')
  677. {
  678. return gdt('See {ref}', {'ref' => docbook_add_id('xref')." linkend=\"$link\"></xref>"});
  679. }
  680. }
  681. else
  682. {
  683. if ($type eq 'ref')
  684. {
  685. return gdt('{title_ref}', {'title_ref' => docbook_add_id('link')." linkend=\"$link\">$title</link>"});
  686. }
  687. elsif ($type eq 'pxref')
  688. {
  689. return gdt('see {title_ref}', {'title_ref' => docbook_add_id('link')." linkend=\"$link\">$title</link>"},{'duplicate'=>1});
  690. }
  691. elsif ($type eq 'xref')
  692. {
  693. return gdt('See {title_ref}', {'title_ref' => docbook_add_id('link')." linkend=\"$link\">$title</link>"},{'duplicate'=>1});
  694. }
  695. }
  696. }
  697. }
  698. sub docbook_external_ref($$$$$$$$$)
  699. {
  700. my $type = shift;
  701. my $section = shift;
  702. my $book = shift;
  703. my $file = shift;
  704. my $href = shift;
  705. my $cross_ref = shift;
  706. my $args_texi = shift;
  707. my $formatted_args = shift;
  708. my $node = shift;
  709. return docbook_any_ref ($type, $formatted_args, $args_texi);
  710. }
  711. sub docbook_internal_ref($$$$$)
  712. {
  713. my $type = shift;
  714. my $href = shift;
  715. my $short_name = shift;
  716. my $name = shift;
  717. my $is_section = shift;
  718. my $args_texi = shift;
  719. my $formatted_args = shift;
  720. return docbook_any_ref ($type, $formatted_args, $args_texi );
  721. }
  722. sub docbook_index_entry_command($$$$$)
  723. {
  724. my $command = shift;
  725. my $index_name = shift;
  726. my $label = shift;
  727. my $entry_texi = shift;
  728. my $entry_formatted = shift;
  729. return $label if (defined($label) and $label ne '');
  730. return docbook_index_entry_label('','','',$main::index_prefix_to_name{$index_name}, '', '', $entry_formatted, {});
  731. }
  732. sub docbook_index_entry_label($$$$$$$$$)
  733. {
  734. my $identifier = shift;
  735. my $preformatted = shift;
  736. my $entry = shift;
  737. my $index_name = shift;
  738. my $index_command = shift;
  739. my $texi_entry = shift;
  740. my $formatted_entry = shift;
  741. my $in_region_not_in_output = shift;
  742. my $index_entry = shift;
  743. return "<indexterm role=\"${index_name}\"><primary>${formatted_entry}</primary></indexterm>";
  744. }
  745. sub docbook_close_section()
  746. {
  747. my $element = $docbook_current_section;
  748. if (!defined($element))
  749. {
  750. return '';
  751. }
  752. my $result = '';
  753. # there is a special case for a @chapter that is a child of @top
  754. # but should not be considered as is, since it is also toplevel.
  755. # @part, however may have other toplevel elements as children.
  756. return '' if ($element->{'child'} and (!$element->{'child'}->{'toplevel'} or $element->{'tag'} ne 'top'));
  757. $result .= '</'.docbook_element_tag($element).">\n";
  758. my $current = $element;
  759. # the second condition is such that top is closed only if it has
  760. # sub-elements below chapter.
  761. # the third condition is such that elements with a next element are
  762. # only closed for the last element, except when the next element is
  763. # toplevel and below top, such that @top is closed before the first
  764. # @chapter if there are @section or the like below @top
  765. while ($current->{'sectionup'} and !($current->{'sectionup'}->{'tag'} eq 'top' and $current->{'toplevel'}) and (!$current->{'childnext'} or ($current->{'childnext'}->{'toplevel'} and $current->{'sectionup'}->{'tag'} eq 'top')))
  766. {
  767. $current = $current->{'sectionup'};
  768. $result .= '</'.docbook_element_tag($current).">\n";
  769. }
  770. return $result;
  771. }
  772. sub docbook_end_section($$$)
  773. {
  774. my $fh = shift;
  775. my $end_foot_navigation = shift;
  776. my $element = shift;
  777. }
  778. sub docbook_print_Top_footer($$)
  779. {
  780. my $fh = shift;
  781. my $end_page = shift;
  782. my $element = shift;
  783. }
  784. sub docbook_one_section($$)
  785. {
  786. my $fh = shift;
  787. my $element = shift;
  788. main::print_lines($fh);
  789. &$print_page_foot($fh);
  790. }
  791. sub docbook_insertcopying($)
  792. {
  793. my $text = shift;
  794. my $comment = shift;
  795. my $simple_text = shift;
  796. return $text;
  797. }
  798. sub docbook_acronym_like($$$$$$)
  799. {
  800. my $command = shift;
  801. my $acronym_texi = shift;
  802. my $acronym_text = shift;
  803. my $with_explanation = shift;
  804. my $explanation_lines = shift;
  805. my $explanation_text = shift;
  806. my $explanation_simply_formatted = shift;
  807. $command = 'abbrev' if ($command eq 'abbr');
  808. my $result = docbook_add_id($command).">$acronym_text</${command}>";
  809. if ($with_explanation)
  810. {
  811. $result .= " ($explanation_text)";
  812. }
  813. return $result;
  814. }
  815. sub docbook_image_files($$$$)
  816. {
  817. my $base = shift;
  818. my $extension = shift;
  819. my $texi_base = shift;
  820. my $texi_extension = shift;
  821. my @files = ();
  822. return @files if (!defined($base) or ($base eq ''));
  823. # FIXME should look at extension argument? makeinfo doesn't
  824. # push @files,"$base.$extension" if (defined($extension) and ($extension ne ''));
  825. foreach my $ext (@IMAGE_EXTENSIONS)
  826. {
  827. push @files, ["$base.$ext", "$texi_base.$ext"];
  828. }
  829. return @files;
  830. }
  831. sub docbook_image($$$$$$$$$$$$$$$$;$)
  832. {
  833. my $file = shift;
  834. my $base = shift;
  835. my $preformatted = shift;
  836. my $file_name = shift;
  837. my $alt = shift;
  838. my $width = shift;
  839. my $height = shift;
  840. my $raw_alt = shift;
  841. my $extension = shift;
  842. my $working_dir = shift;
  843. my $file_path = shift;
  844. my $in_paragraph = shift;
  845. my $file_locations = shift;
  846. my $base_simple_format = shift;
  847. my $extension_simple_format = shift;
  848. my $file_name_simple_format = shift;
  849. my $line_nr = shift;
  850. # if (!defined($file_path) or $file_path eq '' or $file_path =~ /\.txt$/)
  851. # {
  852. # if (defined($extension) and $extension ne '')
  853. # {
  854. # $file = "$base.$extension";
  855. # }
  856. # else
  857. # {
  858. # $file = "$base.jpg";
  859. # $extension = 'jpg';
  860. # }
  861. # main::line_warn ("no image file for $base, (using $file)");
  862. # }
  863. my $txt_path;
  864. my @files = ();
  865. my @extensions = @IMAGE_EXTENSIONS;
  866. foreach my $file_location (@$file_locations)
  867. {
  868. my ($file_located, $path, $file_simple_format) = @$file_location;
  869. my $extension = shift @extensions;
  870. if (defined($path))
  871. {
  872. if ($extension eq 'txt' and !defined($txt_path))
  873. {
  874. $txt_path = $path;
  875. }
  876. else
  877. {
  878. push @files, [$file_located, uc($extension), $file_simple_format];
  879. }
  880. }
  881. }
  882. push @files, ["$base.jpg", 'JPG', "$base_simple_format.jpg" ] unless (@files);
  883. my $begin = docbook_add_id('inlinemediaobject').'>';
  884. my $end = '</inlinemediaobject>';
  885. if ($preformatted or !$in_paragraph)
  886. {
  887. $begin = docbook_add_id('informalfigure').'><mediaobject>';
  888. $end = '</mediaobject></informalfigure>';
  889. }
  890. my $result = $begin;
  891. foreach my $file_spec (@files)
  892. {
  893. $result .= "<imageobject><imagedata fileref=\"$file_spec->[2]\" format=\"$file_spec->[1]\"></imagedata></imageobject>";
  894. }
  895. if (defined($txt_path))
  896. {
  897. if (open(TXT, "<$txt_path"))
  898. {
  899. my $in_encoding = get_conf('IN_ENCODING');
  900. if (defined($in_encoding) and get_conf('USE_UNICODE'))
  901. {
  902. binmode(TXT, ":encoding($in_encoding)");
  903. }
  904. $result.="<textobject><literallayout>";
  905. while (my $img_txt = <TXT>)
  906. {
  907. $result .= $img_txt;
  908. }
  909. $result .= '</literallayout></textobject>';
  910. close(TXT);
  911. }
  912. else
  913. {
  914. main::line_warn (sprintf(__("\@image file `%s' unreadable: %s"), $txt_path, $!), $line_nr);
  915. }
  916. }
  917. else
  918. {
  919. main::line_warn (sprintf(__("Cannot find \@image file `%s.txt'"), $base), $line_nr);
  920. }
  921. return "$result$end";
  922. }
  923. sub docbook_format_list_item_texi($$$$)
  924. {
  925. my $format = shift;
  926. my $line = shift;
  927. my $prepended = shift;
  928. my $command = shift;
  929. my $result_line = undef;
  930. if (defined($command) and $command ne '' and !exists $special_list_commands{$format}->{$command} and $format ne 'itemize')
  931. {
  932. #@*table
  933. $line =~ s/^\s*//;
  934. $line =~ s/\s*$//;
  935. if (exists ($style_map{$command}))
  936. {
  937. $result_line = "\@$command\{$line\}\n";
  938. }
  939. elsif (exists ($things_map{$command}))
  940. {
  941. $result_line = "\@$command\{\} $line\n";
  942. }
  943. else
  944. {
  945. $result_line = "\@$command $line\n";
  946. }
  947. }
  948. return ($result_line, 0);
  949. }
  950. # row in multitable
  951. sub docbook_row($$;$$)
  952. {
  953. my $text = shift;
  954. my $macro = shift;
  955. my $columnfractions = shift;
  956. my $prototype_row = shift;
  957. my $prototype_lengths = shift;
  958. my $column_number = shift;
  959. my $result = '';
  960. if ($macro eq 'headitem')
  961. {
  962. if ($docbook_multitable_stack[-1] != 0)
  963. {
  964. $result .= "<thead>";
  965. $result = "</tbody>" . $result if ($docbook_multitable_stack[-1] == 1);
  966. $docbook_multitable_stack[-1] = 0;
  967. }
  968. }
  969. elsif ($docbook_multitable_stack[-1] != 1)
  970. {
  971. $result .= "<tbody>";
  972. $result = "</thead>" . $result if ($docbook_multitable_stack[-1] == 0);
  973. $docbook_multitable_stack[-1] = 1;
  974. }
  975. $result .= "<row>$text</row>";
  976. return $result;
  977. }
  978. # cell in multitable
  979. sub docbook_cell($$;$$)
  980. {
  981. my $text = shift;
  982. my $row_macro = shift;
  983. my $columnfractions = shift;
  984. my $prototype_row = shift;
  985. my $prototype_lengths = shift;
  986. my $column_number = shift;
  987. return "<entry>" . $text . '</entry>';
  988. }
  989. # if varlistentry_state is > 0 it means that a varlistentry is opened.
  990. # if varlistentry_state is == 2 it means that we are in a succession
  991. # of term
  992. # if varlistentry_state is == 1 it means that we are in the line
  993. # Having a listitem in a varlistentry is a must, so an empty
  994. # listitem is added if a varlistentry is closed and varlistentry_state == 2
  995. #
  996. # varlistentry acceps only term and listitem, so inter_item_commands
  997. # are put in the next term, or, if at the end of the table in a last
  998. # listitem
  999. sub docbook_table_item($$$$$$)
  1000. {
  1001. my $text = shift;
  1002. my $index_label = shift;
  1003. my $format = shift;
  1004. my $command = shift;
  1005. # my $formatted_command = shift;
  1006. my $style_stack = shift;
  1007. # my $text_formatted = shift;
  1008. # my $text_formatted_leading_spaces = shift;
  1009. # my $text_formatted_trailing_spaces = shift;
  1010. my $item_cmd = shift;
  1011. # $formatted_command = '' if (!defined($formatted_command));
  1012. # if (defined($text_formatted))
  1013. # {
  1014. # $text_item = $text_formatted_leading_spaces . $text_formatted .$text_formatted_trailing_spaces;
  1015. # }
  1016. # else
  1017. # {
  1018. # $text_item = $text;
  1019. # }
  1020. my $result = '';
  1021. my $prepended = '';
  1022. if (defined($docbook_table_stack[-1]->{'inter_item'}))
  1023. {
  1024. #$formatted_command = $docbook_table_stack[-1]->{'inter_item'} . $formatted_command;
  1025. $prepended = $docbook_table_stack[-1]->{'inter_item'};
  1026. delete $docbook_table_stack[-1]->{'inter_item'};
  1027. }
  1028. if ($item_cmd eq 'item')
  1029. {
  1030. if ($docbook_table_stack[-1]->{'varlistentry_state'} == 2)
  1031. {
  1032. $result .= "<listitem><para><!-- empty table line --></para></listitem>";
  1033. }
  1034. if ($docbook_table_stack[-1]->{'varlistentry_state'} >= 1)
  1035. {
  1036. $result .= '</varlistentry>';
  1037. }
  1038. $docbook_table_stack[-1]->{'varlistentry_state'} = 2;
  1039. $result .= '<varlistentry>';
  1040. }
  1041. $result .= '<term>';
  1042. $result .= $prepended . $text ."</term>\n";
  1043. return $result;
  1044. }
  1045. sub docbook_table_line($$$)
  1046. {
  1047. my $text = shift;
  1048. my $only_inter_item_commands = shift;
  1049. my $before_items = shift;
  1050. $only_inter_item_commands = '' if (!defined($only_inter_item_commands));
  1051. #print STDERR
  1052. if ($text =~ /\S/)
  1053. {
  1054. if ($before_items)
  1055. {
  1056. return $text;
  1057. }
  1058. if ($only_inter_item_commands)
  1059. {
  1060. $docbook_table_stack[-1]->{'inter_item'} = $text;
  1061. return '';
  1062. }
  1063. else
  1064. {
  1065. $docbook_table_stack[-1]->{'varlistentry_state'} = 1;
  1066. return "<listitem>$text</listitem>";
  1067. }
  1068. #return $text;
  1069. }
  1070. else
  1071. {
  1072. return '';
  1073. }
  1074. }
  1075. sub docbook_list_item($$$$$$$$$)
  1076. {
  1077. my $text = shift;
  1078. my $format = shift;
  1079. my $command = shift;
  1080. my $formatted_command = shift;
  1081. my $item_nr = shift;
  1082. my $enumerate_style = shift;
  1083. my $number = shift;
  1084. my $prepended = shift;
  1085. my $prepended_formatted = shift;
  1086. my $only_inter_item_commands = shift;
  1087. my $before_items = shift;
  1088. $only_inter_item_commands = '' if (!defined($only_inter_item_commands));
  1089. #my $prep_t = 'UNDEF'; $prep_t = $prepended if (defined($prepended));
  1090. #$item_nr = 0 if (!defined($item_nr));
  1091. #print STDERR " $item_nr --> $prep_t|${text}!!!!!\n";
  1092. #return $text if ($only_inter_item_commands and $before_items);
  1093. return $text if ($before_items);
  1094. return '<listitem>' . $text . "</listitem>\n";
  1095. }
  1096. sub docbook_table_list($$$$$$$$$)
  1097. {
  1098. my $format_command = shift;
  1099. my $text = shift;
  1100. my $command = shift;
  1101. my $formatted_command = shift;
  1102. # enumerate
  1103. my $item_nr = shift;
  1104. my $enumerate_style = shift;
  1105. # itemize
  1106. my $prepended = shift;
  1107. my $prepended_formatted = shift;
  1108. # multitable
  1109. my $columnfractions = shift;
  1110. my $prototype_row = shift;
  1111. my $prototype_lengths = shift;
  1112. my $number = shift;
  1113. my $result = "<$format_command>";
  1114. if ($format_command eq 'itemize')
  1115. {
  1116. my $itemfunction;
  1117. #$prepended_formatted =~ s/^\s*// if (defined($prepended_formatted));
  1118. $prepended =~ s/^\s*// if (defined($prepended));
  1119. #if (defined($formatted_command) and $formatted_command ne '')
  1120. if (defined($command) and $command ne '')
  1121. {
  1122. #$itemfunction = $formatted_command;
  1123. $itemfunction = $command;
  1124. #$itemfunction .= " $prepended_formatted" if (defined($prepended_formatted) and $prepended_formatted ne '');
  1125. $itemfunction .= " $prepended" if (defined($prepended) and $prepended ne '');
  1126. }
  1127. #elsif (defined($prepended_formatted))
  1128. elsif (defined($prepended))
  1129. {
  1130. #$itemfunction = $prepended_formatted;
  1131. $itemfunction = $prepended;
  1132. }
  1133. my $mark = '';
  1134. $mark = " mark=\"$itemfunction\"" if (defined($itemfunction) and $itemfunction ne '');
  1135. return docbook_add_id('itemizedlist')."${mark}>$text</itemizedlist>";
  1136. }
  1137. elsif ($format_command eq 'enumerate')
  1138. {
  1139. my $numeration='arabic';
  1140. if (defined($enumerate_style) and $enumerate_style ne '')
  1141. {
  1142. if ($enumerate_style =~ /^[A-Z]/)
  1143. {
  1144. $numeration = 'upperalpha';
  1145. }
  1146. elsif ($enumerate_style =~ /^[a-z]/)
  1147. {
  1148. $numeration = 'loweralpha';
  1149. }
  1150. }
  1151. return docbook_add_id('orderedlist') ." numeration=\"$numeration\">$text</orderedlist>";
  1152. }
  1153. elsif ($format_command eq 'multitable')
  1154. {
  1155. my $result = docbook_add_id('informaltable').'><tgroup cols="'.$number.'">';
  1156. my $fractions;
  1157. my $multiply = 1;
  1158. if (defined($columnfractions) and (ref($columnfractions) eq 'ARRAY')
  1159. and scalar(@$columnfractions))
  1160. {
  1161. $fractions = [ @$columnfractions ];
  1162. $multiply = 100;
  1163. }
  1164. elsif (defined($prototype_lengths) and (ref($prototype_lengths) eq 'ARRAY')
  1165. and scalar(@$prototype_lengths))
  1166. {
  1167. $fractions = [ @$prototype_lengths ];
  1168. }
  1169. if (defined ($fractions))
  1170. {
  1171. foreach my $fraction (@$fractions)
  1172. {
  1173. $result .= '<colspec colwidth="'.($fraction*$multiply).'*"></colspec>';
  1174. }
  1175. }
  1176. $text .= "</tbody>" if ($docbook_multitable_stack[-1] == 1);
  1177. $text .= "</thead>" if ($docbook_multitable_stack[-1] == 0);
  1178. pop @docbook_multitable_stack;
  1179. return $result . "$text</tgroup></informaltable>";
  1180. }
  1181. elsif ($format_command =~ /^(v|f)?table$/)
  1182. {
  1183. $result = docbook_add_id('variablelist').'>';
  1184. if (defined($docbook_table_stack[-1]->{'inter_item'}))
  1185. { # there is a para in case there is only a comment, to avoid
  1186. # an empty listitem
  1187. $text .= "<listitem><para>$docbook_table_stack[-1]->{'inter_item'}</para></listitem>";
  1188. }
  1189. elsif ($docbook_table_stack[-1]->{'varlistentry_state'} == 2)
  1190. {
  1191. $text .= "<listitem><para><!-- empty table line --></para></listitem>";
  1192. }
  1193. $text .= '</varlistentry>' if ($docbook_table_stack[-1]->{'varlistentry_state'} >= 1);
  1194. pop @docbook_table_stack;
  1195. return $result . "$text</variablelist>\n";
  1196. }
  1197. }
  1198. sub docbook_begin_format_texi($$$)
  1199. {
  1200. my $command = shift;
  1201. my $line = shift;
  1202. my $state = shift;
  1203. push (@docbook_multitable_stack, -1) if ($command eq 'multitable');
  1204. push (@docbook_table_stack, {'varlistentry_state' => 0}) if ($command =~ /^(v|f)?table/);
  1205. return $line;
  1206. }
  1207. # FIXME
  1208. sub docbook_sp($$)
  1209. {
  1210. my $number = shift;
  1211. my $preformatted = shift;
  1212. return "";
  1213. }
  1214. sub docbook_index_summary($$)
  1215. {
  1216. my $alpha = shift;
  1217. my $nonalpha = shift;
  1218. return '';
  1219. }
  1220. sub docbook_printindex($$)
  1221. {
  1222. my $name = shift;
  1223. my $printindex = shift;
  1224. return docbook_add_id('index')."></index>\n";
  1225. }
  1226. sub docbook_complex_format($$)
  1227. {
  1228. my $name = shift;
  1229. my $text = shift;
  1230. return '' if ($text eq '');
  1231. my $result = docbook_add_id($docbook_complex_format{$name}).'>' .$text."</$docbook_complex_format{$name}>";
  1232. return $result;
  1233. }
  1234. sub docbook_format($$)
  1235. {
  1236. my $name = shift;
  1237. my $element = shift;
  1238. my $text = shift;
  1239. return '' if ($text eq '');
  1240. return $text if ($format_map{$name} eq '');
  1241. if ($name eq 'copying')
  1242. {
  1243. # FIXME is info in docbook 5.0
  1244. return "<bookinfo>\n<legalnotice>\n$text</legalnotice>\n</bookinfo>\n";
  1245. }
  1246. return docbook_add_id($format_map{$name}).'>' .$text."</$format_map{$name}>";
  1247. }
  1248. sub docbook_quotation_prepend_text($$)
  1249. {
  1250. my $command = shift;
  1251. my $argument_text = shift;
  1252. return undef if (!defined($argument_text) or $argument_text =~ /^$/);
  1253. chomp($argument_text);
  1254. return undef if (grep {lc($argument_text) eq $_} @docbook_special_quotation);
  1255. return gdt('@b{{quotation_arg}:} ', {'quotation_arg' => $argument_text}, {'keep_texi' => 1});
  1256. }
  1257. sub docbook_quotation($$$$$)
  1258. {
  1259. my $command = shift;
  1260. my $text = shift;
  1261. my $argument_text = shift;
  1262. my $argument_text_texi = shift;
  1263. my $authors = shift;
  1264. $argument_text_texi = '' if (!defined($argument_text_texi));
  1265. chomp($argument_text_texi);
  1266. my $docbook_command = 'blockquote';
  1267. if (grep {lc($argument_text_texi) eq $_} @docbook_special_quotation)
  1268. {
  1269. $docbook_command = lc($argument_text_texi);
  1270. }
  1271. my $attribution = '';
  1272. if ($authors)
  1273. {
  1274. foreach my $author (@$authors)
  1275. {
  1276. $attribution .= $author->{'author_text'};
  1277. }
  1278. $attribution = '<attribution>' .$attribution. '</attribution>' . "\n";
  1279. }
  1280. return docbook_add_id($docbook_command).'>' .$attribution . $text . "</$docbook_command>\n";
  1281. }
  1282. sub docbook_style($$$$$$$$$)
  1283. {
  1284. my $style = shift;
  1285. my $command = shift;
  1286. my $text = shift;
  1287. my $args = shift;
  1288. my $no_close =shift;
  1289. my $no_open = shift;
  1290. my $line_nr = shift;
  1291. my $state = shift;
  1292. my $command_stack = shift;
  1293. my $kept_line_nrs = shift;
  1294. my $result = $text;
  1295. if (exists($style->{'function'}))
  1296. {
  1297. my $function = $style->{'function'};
  1298. $result = &$function($command, $args, $command_stack, $state, $line_nr, $kept_line_nrs);
  1299. }
  1300. elsif (exists($style->{'inline_attribute'}))
  1301. {
  1302. my $element = $style->{'inline_attribute'};
  1303. my $attribute_text = '';
  1304. if ($element =~ /^(\w+)(\s+.*)/)
  1305. {
  1306. $element = $1;
  1307. $attribute_text = $2;
  1308. }
  1309. if ($no_open)
  1310. {
  1311. $result = "<$element";
  1312. }
  1313. else
  1314. {
  1315. $result = docbook_add_id($element);
  1316. }
  1317. $result .= "$attribute_text>$text</$element>";
  1318. }
  1319. if (exists($style->{'begin'}) and !$no_open)
  1320. {
  1321. $result = $style->{'begin'} . $result;
  1322. }
  1323. if (exists($style->{'end'}) and !$no_close)
  1324. {
  1325. $result .= $style->{'end'};
  1326. }
  1327. return $result;
  1328. }
  1329. sub docbook_raw($$$)
  1330. {
  1331. my $style = shift;
  1332. my $text = shift;
  1333. my $line_nr = shift;
  1334. if ($style eq 'verbatim' or $style eq 'verbatiminclude')
  1335. {
  1336. return docbook_add_id('screen').'>' . &$protect_text($text) . '</screen>';
  1337. }
  1338. return '' unless (grep {$style eq $_} @EXPAND);
  1339. if ($style eq 'docbook')
  1340. {
  1341. chomp ($text);
  1342. return $text;
  1343. }
  1344. else
  1345. {
  1346. main::line_warn (sprintf(__("Raw format %s is not converted"), $style), $line_nr);
  1347. return &$protect_text($text);
  1348. }
  1349. }
  1350. sub docbook_cartouche($$)
  1351. {
  1352. my $text = shift;
  1353. return $text;
  1354. }
  1355. sub docbook_anchor_label($$)
  1356. {
  1357. my $id = shift;
  1358. my $anchor_text = shift;
  1359. # FIXME use docbook_node_id
  1360. return '<anchor id="'. &$protect_text($anchor_text) . '"></anchor>';
  1361. }
  1362. sub docbook_float($$$$$)
  1363. {
  1364. my $text = shift;
  1365. my $float = shift;
  1366. my $caption = shift;
  1367. my $shortcaption = shift;
  1368. my $label_texi = $float->{'texi'};
  1369. return $text if (!defined($label_texi) or $label_texi eq '');
  1370. return docbook_anchor_label('',$label_texi) . $text;
  1371. }
  1372. sub docbook_normal_text($$$$$$$;$)
  1373. {
  1374. my $text = shift;
  1375. my $in_raw_text = shift; # remove_texi
  1376. my $in_preformatted = shift;
  1377. my $in_code = shift;
  1378. my $in_math = shift;
  1379. my $in_simple = shift;
  1380. #print STDERR "Bug: in_raw_text in_simple $text\n" if ($in_raw_text and $in_simple);
  1381. my $style_stack = shift;
  1382. my $state = shift;
  1383. #$text = uc($text) if (in_cmd($style_stack, 'sc'));
  1384. $text = &$protect_text($text) unless($in_raw_text);
  1385. if (! $in_code and !$in_preformatted)
  1386. {
  1387. if (!$in_raw_text)
  1388. {
  1389. $text =~ s/---/\&mdash\;/g;
  1390. $text =~ s/--/\&ndash\;/g;
  1391. $text =~ s/``/\&ldquo\;/g;
  1392. $text =~ s/''/\&rdquo\;/g;
  1393. }
  1394. else
  1395. {
  1396. #FIXME really do that ? It is done by makeinfo in html
  1397. $text =~ s/``/"/g;
  1398. $text =~ s/''/"/g;
  1399. # FIXME really do that in raw text?
  1400. $text =~ s/---/\x{1F}/g;
  1401. $text =~ s/--/-/g;
  1402. $text =~ s/\x{1F}/--/g;
  1403. }
  1404. }
  1405. return $text;
  1406. }
  1407. sub docbook_noop
  1408. {
  1409. return '';
  1410. }
  1411. 1;