123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663 |
- # vim: set filetype=perl:
- #
- #+##############################################################################
- #
- # info.pm: convert to info
- #
- # Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 3 of the License,
- # or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- #
- #
- # Some error messages come from texinfo (makeinfo), so copyright holder
- # is the FSF or the individual who wrote them. All come from before the
- # switch of texinfo to GPLv3+.
- #
- #
- # Originally written by Patrice Dumas.
- #
- #-##############################################################################
- use Data::Dumper;
- use strict;
- $Data::Dumper::Maxdepth = 25;
- my %info_default_indented_commands;
- my %info_default_format;
- my %info_default_enable_encoding_accents;
- my @simple_quoted_commands;
- my @asis_commands;
- my @chevron_commands;
- my %info_default_accent_commands = ();
- my %info_default_leaf_command = ();
- my $info_default_end_sentence_character;
- my $info_default_after_punctuation_characters;
- my $info_default_indent_length;
- my %info_default_indent_format_length;
- my $info_default_index_length_to_node;
- my $info_default_listoffloat_caption_entry_length;
- my $info_default_listoffloat_append;
- my %info_default_index_entries_counts;
- sub info_default_load(;$)
- {
- my $from_command_line = shift;
- t2h_default_set_variables_default();
- set_default('USE_SECTIONS', 0);
- set_default('USE_NODES', 1);
- set_default('SPLIT', '');
- @T2H_FORMAT_EXPAND = ('info', 'direntry');
- set_default('EXTENSION', 'info');
- set_default('SHOW_MENU', 1);
- set_default('SHOW_TITLE', 0);
- set_default('USE_SETFILENAME_EXTENSION', 1);
- set_default('INLINE_INSERTCOPYING', 1);
- set_default('SIMPLE_MENU', 1);
- $MENU_SYMBOL = '*';
- set_default('ENABLE_ENCODING_USE_ENTITY', 0);
- set_default('ENABLE_ENCODING', 1);
- @IMAGE_EXTENSIONS = ('png', 'jpg', 'txt');
- $CAPTION_STYLE = 'asis';
- set_default('DEFAULT_ENCODING', 'ascii');
- set_default('HEADERS', 1);
- set_default('INLINE_CONTENTS', 0);
- $no_paragraph_commands{'anchor'} = 1;
- %simple_map = %default_simple_map;
- %simple_map_pre = %simple_map;
- %simple_map_texi = %simple_map;
- %things_map = %default_things_map;
- %pre_map = %things_map;
- %line_command_map = (
- 'dircategory' => ''
- );
- # sc and var upcase.
- @simple_quoted_commands = ('cite', 'code', 'command', 'env', 'file', 'kbd',
- 'option', 'samp');
- @asis_commands = ('asis', 'w', 'b', 'ctrl', 'i', 'math', 'sc', 't', 'r',
- 'slanted', 'sansserif', 'var', 'titlefont', 'verb', 'clickstyle',
- 'headitemfont');
- @chevron_commands = ('key', 'indicateurl');
- %info_default_accent_commands = ();
- %info_default_leaf_command = ();
- %style_map = ();
- t2h_default_copy_style_map (\%default_style_map, \%style_map);
- foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents), keys(%accent_map))
- {
- $info_default_accent_commands{$accent_command} = 1;
- $style_map{$accent_command} = { 'function' => \&info_default_accent };
- }
- foreach my $command (keys(%style_map))
- {
- delete $style_map{$command}->{'quote'} if (exists($style_map{$command}->{'quote'}));
- if (grep {$_ eq $command} @simple_quoted_commands)
- {
- delete $style_map{$command}->{'function'} if (exists($style_map{$command}->{'function'}));
- $style_map{$command}->{'begin'} = '`';
- $style_map{$command}->{'end'} = "'";
- next;
- }
- elsif (grep {$_ eq $command} @asis_commands)
- {
- delete $style_map{$command}->{'function'} if (exists($style_map{$command}->{'function'}));
- delete $style_map{$command}->{'begin'} if (exists($style_map{$command}->{'begin'}));
- delete $style_map{$command}->{'end'} if (exists($style_map{$command}->{'end'}));
- }
- if (grep {$_ eq $command} @chevron_commands)
- {
- delete $style_map{$command}->{'function'} if (exists($style_map{$command}->{'function'}));
- $style_map{$command}->{'begin'} = '<';
- $style_map{$command}->{'end'} = '>';
- next;
- }
- $info_default_leaf_command{$command} = 1 if ($style_map{$command}->{'type'} and $style_map{$command}->{'type'} eq 'simple_style');
- }
- $style_map{'strong'}->{'begin'} = '*';
- $style_map{'strong'}->{'end'} = '*';
- $style_map{'dfn'}->{'begin'} = '"';
- $style_map{'dfn'}->{'end'} = '"';
- $style_map{'emph'}->{'begin'} = '_';
- $style_map{'emph'}->{'end'} = '_';
- foreach my $command (keys(%info_default_leaf_command))
- {
- if (defined ($style_map{$command}->{'args'}))
- {
- $style_map{$command}->{'orig_args'} = [ @{$style_map{$command}->{'args'}} ];
- }
- else
- {
- $style_map{$command}->{'orig_args'} = [ 'normal' ];
- }
- $style_map{$command}->{'args'} = [];
- foreach my $arg (@{$style_map{$command}->{'orig_args'}})
- {
- push @{$style_map{$command}->{'args'}}, 'keep';
- }
- }
- $style_map{'uref'}->{'function'} = \&info_default_uref;
- $style_map{'url'}->{'function'} = \&info_default_uref;
- $style_map{'email'}->{'function'} = \&info_default_email;
- %style_map_pre = ();
- %style_map_texi = ();
- t2h_default_copy_style_map (\%style_map, \%style_map_pre);
- t2h_default_copy_style_map (\%style_map, \%style_map_texi);
- $special_list_commands{'itemize'} = {};
- %info_default_indent_format_length = ('enumerate' => 2,
- 'itemize' => 3,
- 'table' => 0,
- 'vtable' => 0,
- 'ftable' => 0,
- );
- %format_map = ();
- foreach my $format ('group', 'raggedright', 'cartouche')
- {
- $format_map{$format} = '';
- }
- foreach my $menu_command('menu', 'detailmenu', 'direntry', 'menu_comment')
- {
- $complex_format_map{$menu_command} = {'begin' => '' , 'end' => ''};
- }
- foreach my $command (keys (%complex_format_map), keys(%info_default_indent_format_length), 'quotation', 'smallquotation', 'deff_item', 'deff_itemx')
- {
- $info_default_indented_commands{$command} = 1;
- }
- foreach my $command (keys(%info_default_indented_commands), 'multitable', 'float', 'flushright', 'flushleft', 'center')
- {
- $info_default_format{$command} = 1;
- }
- # it doesn't change anything for multitable
- foreach my $non_indented_command('format', 'smallformat', 'menu',
- 'detailmenu', 'direntry', 'multitable')
- {
- $info_default_indented_commands{$non_indented_command} = 0;
- }
- $info_default_end_sentence_character = quotemeta($punctuation_characters);
- $info_default_after_punctuation_characters = quotemeta($after_punctuation_characters);
- $info_default_indent_length = 5;
- $info_default_index_length_to_node = 41;
- $info_default_listoffloat_caption_entry_length = 41;
- $info_default_listoffloat_append = '...';
- t2h_default_push_handler(\&info_default_init_accent_enable_encoding, \@command_handler_init);
- t2h_default_push_handler(\&info_default_init_variables, \@command_handler_init);
- $style = \&info_default_style;
- $print_page_head = \&info_default_print_page_head;
- $contents = \&info_default_noop;
- $shortcontents = \&info_default_noop;
- $about_body = \&info_default_noop;
- $print_Footnotes = \&info_default_noop;
- $copying_comment = \&info_default_copying_comment;
- $element_heading = \&info_default_element_heading;
- $heading = \&info_default_heading;
- $normal_text = \&info_default_normal_text;
- $paragraph = \&info_default_paragraph;
- $preformatted = \&info_default_preformatted;
- $empty_preformatted = \&info_default_preformatted;
- $empty_line = \&info_default_empty_line;
- # maybe should not be called from the main program?
- $print_page_foot = \&info_default_print_page_foot;
- $print_Top_footer = \&info_default_print_Top_footer;
- $print_Top = \&info_default_print_section;
- $print_section = \&info_default_print_section;
- $end_section = \&info_default_end_section;
- $one_section = \&info_default_one_section;
- $begin_format_texi = \&info_default_begin_format_texi;
- $begin_style_texi = \&info_default_begin_style_texi;
- $begin_paragraph_texi = \&info_default_begin_paragraph_texi;
- $simple_command = \&info_default_simple_command;
- $thing_command = \&info_default_thing_command;
- $begin_special_region = \&info_default_begin_special_region;
- $end_special_region = \&info_default_end_special_region;
- $anchor_label = \&info_default_anchor_label;
- $element_label = \&info_default_noop;
- $menu_link = \&info_default_menu_link;
- #$menu_command = \&info_default_menu_command;
- $complex_format = \&info_default_complex_format;
- $quotation = \&info_default_quotation;
- $misc_command_line = \&info_default_misc_commands;
- $external_ref = \&info_default_external_ref;
- $internal_ref = \&info_default_internal_ref;
- $image = \&info_default_image;
- $image_files = \&info_default_image_files;
- $index_summary = \&info_default_index_summary;
- $summary_letter = \&info_default_summary_letter;
- $index_entry = \&info_default_index_entry;
- $index_entry_command = \&t2h_default_index_entry_command;
- $index_letter = \&info_default_index_letter;
- $printindex = \&info_default_printindex;
- $print_index = \&info_default_print_index;
- $index_entry_label = \&info_default_index_entry_label;
- $foot_section = \&info_default_foot_lines;
- $foot_line_and_ref = \&info_default_foot_line_and_ref;
- $footnote_texi = \&info_default_footnote_texi;
- $list_item = \&info_default_list_item;
- $format_list_item_texi = \&info_default_format_list_item_texi;
- $format = \&info_default_format;
- $tab_item_texi = \&info_default_tab_item_texi;
- $acronym_like = \&info_default_acronym_like;
- $sp = \&info_default_sp;
- $paragraph_style_command = \&info_default_paragraph_style_command;
- $cell = \&info_default_cell;
- $row = \&info_default_row;
- $table_list = \&info_default_table_list;
- $def_item = \&info_default_def_item;
- $def = \&info_default_def;
- $def_line = \&info_default_def_line;
- $float = \&info_default_float;
- $listoffloats_entry = \&info_default_listoffloats_entry;
- $listoffloats = \&info_default_listoffloats;
- $colon_command = \&info_default_colon_command;
- $raw = \&info_default_raw;
- $line_command = \&info_default_line_command;
- $comment = \&t2h_default_comment;
- $unknown_style = \&info_default_unknown_style;
- $heading_text = \&t2h_default_heading_text;
- }
- my %info_default_state_map = ();
- my $info_default_out_file_nr = 1;
- my $info_default_dir_specification = '';
- my @info_default_pending_indirect = ();
- my @info_default_pending_footnotes = ();
- my $info_default_state_nr = 0;
- # maximal length of index entries line number information. Each entry is
- # an index name.
- my %info_default_index_line_string_length = ();
- my %info_default_index_entries = ();
- my $info_default_footnote_index = 0;
- my $info_default_current_node = undef;
- my %info_default_command_handler_expand;
- sub info_default_intercept_handler
- {
- my $command = $_[0];
- my $result = &{$info_default_command_handler_expand{$command}}(@_);
- return info_default_store_text (undef, $result, $command);
- }
- sub info_default_init_variables()
- {
- %info_default_state_map = ();
- $info_default_out_file_nr = 1;
- $info_default_dir_specification = '';
- @info_default_pending_indirect = ();
- @info_default_pending_footnotes = ();
- $info_default_state_nr = 0;
- %info_default_index_line_string_length = ();
- %info_default_index_entries = ();
- $info_default_footnote_index = 0;
- $info_default_current_node = undef;
- #$Texi2HTML::THISDOC{'SPLIT'} = 0 if ($OUTPUT_FORMAT eq 'info');
- #$FRAMES = 0 if ($OUTPUT_FORMAT eq 'info');
- foreach my $command (keys (%command_handler))
- {
- if ($command_handler{$command}->{'expand'})
- {
- $info_default_command_handler_expand{$command} = $command_handler{$command}->{'expand'};
- $command_handler{$command}->{'expand'} = \&info_default_intercept_handler;
- }
- }
- }
- # this is put in command_handler_init such that it sets things right
- # in case ENABLE_ENCODING is set and has lead to modification of the
- # accent functions
- sub info_default_init_accent_enable_encoding()
- {
- return unless (get_conf('ENABLE_ENCODING') and get_conf('USE_UNICODE'));
- foreach my $key (keys(%unicode_accents), 'dotless')
- {
- $info_default_enable_encoding_accents{$key} = 1;
- $t2h_enable_encoding_default_accent{'normal'}->{$key} = \&t2h_default_accent;
- $t2h_enable_encoding_default_accent{'texi'}->{$key} = \&t2h_default_accent;
- $t2h_enable_encoding_default_accent{'pre'}->{$key} = \&t2h_default_accent;
- $style_map{$key}->{'function'} = \&info_default_accent;
- $style_map_texi{$key}->{'function'} = \&info_default_accent;
- $style_map_pre{$key}->{'function'} = \&info_default_accent;
- }
- }
- sub info_default_uref($$)
- {
- shift;
- my $args = shift;
- my $url = shift @$args;
- my $text = shift @$args;
- my $replacement = shift @$args;
- $url = main::normalise_space($url);
- $replacement = '' if (!defined($replacement));
- $replacement = main::normalise_space($replacement);
- return $replacement if ($replacement ne '');
- $text = '' if (!defined($text));
- $text = main::normalise_space($text);
- return "`$url'" if ($text eq '');
- return "$text ($url)";
- }
- sub info_default_email($$)
- {
- my $command = shift;
- my $args = shift;
- my $mail = shift @$args;
- my $text = shift @$args;
- $mail = main::normalise_space($mail);
- $text = '' if (!defined($text));
- $text = main::normalise_space($text);
- $mail = "<$mail>";
- return $mail unless ($text ne '');
- return "$text $mail";
- }
- sub info_default_accent($$$)
- {
- my @args = @_;
- my $command = shift;
- my $args = shift;
- my $text = $args->[0];
- my $style_stack = shift;
- my $state = shift;
- my $result;
- if (get_conf('ENABLE_ENCODING') and $info_default_enable_encoding_accents{$command})
- {
- $result = &t2h_enable_encoding_normal_accent(@args);
- }
- else
- {
- $result = &t2h_default_accent(@args);
- }
- if (scalar(@$style_stack) and $info_default_accent_commands{$style_stack->[-1]})
- { # still more accents on the stack
- return $result;
- }
- return info_default_store_text($state,$result,'accents_commands');
- }
- sub info_default_noop
- {
- return '';
- }
- sub info_default_copying_comment($$$$)
- {
- my $copying_lines = shift;
- my $copying_text = shift;
- my $copying_no_texi = shift;
- my $copying_simple_text = shift;
- return '' if ($copying_text eq '');
- return $copying_text;
- }
- sub info_default_byte_count($)
- {
- my $string = shift;
- my $out_encoding = get_conf('OUT_ENCODING');
- if ($out_encoding and lc($out_encoding) ne 'us-ascii' and get_conf('USE_UNICODE'))
- {
- return length (Encode::encode($out_encoding, $string));
- }
- # There is no default encoding. We assume it is us-ascii. Not sure
- # about what perl thinks it is...
- #print STDERR "Unknown encoding for: $string\n" if (!$out_encoding);
- return length($string);
- }
- sub info_default_count_lines($;$$)
- {
- my $text = shift;
- my $indent_length = shift;
- my $indentation_done = shift;
- my $blank_line;
- my $no_indentation = 0;
-
- if (!defined($indentation_done) or $indentation_done)
- {
- $no_indentation = 1;
- $indent_length = 0;
- }
- my @lines = split /^/, $text;
- # don't accept empty text.
- @lines = ('') if (!@lines);
- my $line_passed = scalar(@lines);
- $line_passed-- if ($line_passed);
- my $end_of_line = 0;
- if (($#lines > 1) and !$end_of_line and ($lines[-1] !~ /\S/) and ($lines[-2] !~ /\S/))
- {
- $blank_line = 1;
- }
- my $last_line = $lines[-1];
- my $indented_text = shift (@lines);
- #print STDERR "COUNT info_default_count_lines(i_done $no_indentation, i_l $indent_length) i_t `$indented_text'\n";
- foreach my $line (@lines)
- {
- if ($indent_length and $line =~ /\S/)
- {
- $indented_text .= ' ' x $indent_length . $line;
- }
- else
- {
- $indented_text .= $line;
- }
- }
- if (chomp($text))
- {
- $line_passed++;
- $end_of_line = 1;
- }
- return ($line_passed, $end_of_line, $last_line, $indented_text, $blank_line);
- }
- sub info_default_get_state($)
- {
- my $state = shift;
- if (!exists $info_default_state_map{$state})
- {
- #print STDERR "NEW state $info_default_state_nr\n";
- my ($current_command, $top_stack);
- $info_default_state_map{$state} = {};
- info_default_reset_state($info_default_state_map{$state});
- # since the page head always leave a blank line, and the state may be
- # used for text right after the page head, we set it to 1 here.
- # it may be wrong in other contexts, to be seen.
- $info_default_state_map{$state}->{'blank_line'} = 1;
- $info_default_state_map{$state}->{'only_spaces'} = 1;
- # this is the first line, so set to 1. This is reset later in
- # most cases, when a node is seen, but may still be useful in
- # @footnote, for example
- $info_default_state_map{$state}->{'line_count'} = 1;
- $info_default_state_map{$state}->{'offset_in_file'} = 0;
- $info_default_state_map{$state}->{'nr'} = $info_default_state_nr;
- $info_default_state_map{$state}->{'state'} = $state;
- $info_default_state_map{$state}->{'multitable_stack'} = [];
- @{$info_default_state_map{$state}->{'align_stack'}} = ({'command'=>'normal'});
- $info_default_state_nr++;
- }
- #print STDERR "RETURN state $state $info_default_state_map{$state} $info_default_state_map{$state}->{'nr'}\n";
- return $info_default_state_map{$state};
- }
- sub info_default_reset_state($)
- {
- my $info_state = shift;
- $info_state->{'top'} = {};
- $info_state->{'current'} = $info_state->{'top'};
- }
- sub info_default_iterator_next($$$)
- {
- my $current_command = shift;
- my $command_index = shift;
- my $command_close = shift;
- #print STDERR "NNNNNNNNNNNNNN iterator_next current $current_command idx $command_index close $command_close\n";
-
- my $sub_command = $current_command->{'content'}->[$command_index];
-
- if ($sub_command->{'content'} and !$command_close)
- {
- return ($sub_command, 0, 0);
- }
-
- if ($current_command->{'content'}->[$command_index+1])
- {
- return ($current_command, $command_index+1, 0);
- }
- elsif (defined($current_command->{'parent'}))
- {
- return ($current_command->{'parent'}, $current_command->{'index_in_parent'}, 1);
- }
- else
- {
- return (undef, undef, undef);
- }
- }
- # return ($current_next, $index_next, $close_next, $text, $command);
- #
- # returns the next in tree, identified by the triplet
- # ($current_next, $index_next, $close_next) and also the command
- # and/or text if defined, in $text and $command.
- sub info_default_next($$$)
- {
- my $current = shift;
- my $index = shift;
- my $close = shift;
- my $text;
- my $command;
- my ($current_next, $index_next, $close_next) = info_default_iterator_next($current, $index, $close);
- return ($current_next, $index_next, $close_next, $text, $command) if (!defined($current_next));
- my $content = $current_next->{'content'}->[$index_next];
- $command = $content->{'command'} if (defined($content->{'command'}));
- if ($close_next)
- {
- return ($current_next, $index_next, $close_next, $content->{'end'}, $command);
- }
- if (defined($content->{'text'}))
- {
- return ($current_next, $index_next, $close_next, $content->{'text'}, $command);
- }
- if (defined($content->{'begin'}))
- {
- $text = $content->{'begin'};
- }
- if (defined($content->{'end'}) and !defined($content->{'content'}))
- {
- if (!defined($text))
- {
- $text = $content->{'end'};
- }
- else
- {
- $text .= $content->{'end'};
- }
- }
- return ($current_next, $index_next, $close_next, $text, $command);
- }
- sub info_default_process_line_text($$$)
- {
- my $text = shift;
- my $line_width_counter = shift;
- my $indent_length = shift;
- $indent_length = 0 if (!defined($indent_length));
- my $line_passed = 0;
- my $chomped_text = $text;
- my $end_of_line = chomp($chomped_text);
- if ($indent_length > $line_width_counter and $chomped_text ne '')
- {
- $text = ' ' x ($indent_length - $line_width_counter) . $text;
- }
- $line_width_counter += t2h_default_string_width($text);
- # it seems like it never happens in the tests.
- if ($end_of_line)
- {
- $line_passed = 1;
- $line_width_counter = 0;
- }
- return ($line_width_counter, $line_passed, $text);
- }
- # Beware that there is a pending word if the text doesn't end with
- # a space
- sub info_default_process_para_text($$$$$;$$)
- {
- my $text = shift;
- my $line_char_counter = shift;
- my $pending_spaces_word = shift;
- my $indent_length = shift;
- my $max_column = shift;
- my $keep_end_of_lines = shift;
- $keep_end_of_lines = 0 if (!$keep_end_of_lines);
- # indentation for the lines except for the first one
- my $indent_length_next = shift;
- $indent_length = 0 if (!defined($indent_length));
- $indent_length_next = $indent_length if (!defined($indent_length_next));
-
- my $line_passed = 0;
- my $result = '';
- #print STDERR "process_text(indent($indent_length,$indent_length_next),keep_eol $keep_end_of_lines) spaces `$pending_spaces_word->{'spaces'}') line_char_counter $line_char_counter |$text|\n";
-
- while ($text ne '')
- {
- #print STDERR "l_c_c $line_char_counter pending_word ".var_to_str($pending_spaces_word->{'word'}).", pending_spaces `$pending_spaces_word->{'spaces'}', result `$result'\n";
- if (!$keep_end_of_lines and $text =~ s/^(\s+)//)
- {
- my $new_spaces = $1;
- # in general there are no end of lines in the lines cut, since they
- # are replaced by spaces in the main loop. However, it may happen
- # with @* in @def* lines
- my @lines = split /^/, $new_spaces;
- my $eol_spaces;
- # last line is in $new_spaces, other lines are in $eol_spaces
- if (@lines > 1)
- {
- $new_spaces = pop @lines;
- $eol_spaces = join ("", @lines);
- #print STDERR "EOL_SPACES[$line_char_counter](+$pending_spaces_word->{'spaces'}) `$eol_spaces'\n";
- }
- if (defined($pending_spaces_word->{'word'}))
- {
- # add spaces in front if needed for the indentation
- if ($indent_length > $line_char_counter + t2h_default_string_width($pending_spaces_word->{'spaces'}))
- {
- $pending_spaces_word->{'spaces'} = ' ' x ($indent_length - $line_char_counter) . $pending_spaces_word->{'spaces'};
- }
- $result .= $pending_spaces_word->{'spaces'} . $pending_spaces_word->{'word'};
- $line_char_counter += t2h_default_string_width($pending_spaces_word->{'spaces'})+t2h_default_string_width($pending_spaces_word->{'word'});
- $pending_spaces_word->{'spaces'} = $new_spaces;
- $pending_spaces_word->{'word'} = undef;
- }
- elsif (!$eol_spaces)
- {
- $pending_spaces_word->{'spaces'} .= $new_spaces;
- }
- if ($eol_spaces)
- {
- $result .= $eol_spaces;
- $line_passed += scalar(@lines);
- $indent_length = $indent_length_next;
- $line_char_counter = 0;
- $pending_spaces_word->{'spaces'} = '';
- }
- if ((t2h_default_string_width($pending_spaces_word->{'spaces'}) + $line_char_counter > $max_column))
- {
- $pending_spaces_word->{'spaces'} = '';
- $result .= "\n";
- $line_passed++;
- $indent_length = $indent_length_next;
- $line_char_counter = 0;
- }
- }
- else
- {
- my $word;
- if ($keep_end_of_lines)
- {
- $word = $text;
- $text = '';
- }
- elsif ($text =~ s/^([^\s]+)//)
- {
- $word = $1;
- }
- #else
- #{
- # die "BUG: Impossible situation.\n";
- #}
- $pending_spaces_word->{'word'} = '' if (!defined($pending_spaces_word->{'word'}));
- $pending_spaces_word->{'word'} .= $word;
- # The $line_char_counter != 0 is here to cope with the case of a
- # word longer than $line_char_counter followed by more text:
- # a line would be passed each time some piece text is appended.
- if ((t2h_default_string_width($pending_spaces_word->{'spaces'})+t2h_default_string_width($pending_spaces_word->{'word'}) + $line_char_counter > $max_column) and $line_char_counter != 0)
- {
- $pending_spaces_word->{'spaces'} = '';
- $result .= "\n";
- $line_passed++;
- $indent_length = $indent_length_next;
- $line_char_counter = 0;
- }
- }
- }
- return ($line_char_counter, $pending_spaces_word, $line_passed, $result)
- }
- sub info_default_skip_spaces($$$)
- {
- my $current = shift;
- my $index = shift;
- my $close = shift;
- #print STDERR "SKIP_SPACES\n";
- while(1)
- {
- my ($current_next, $index_next, $close_next) = info_default_iterator_next($current, $index, $close);
- return if ($close_next or (!defined($current_next)));
- my $content = $current_next->{'content'}->[$index_next];
- if (defined($content->{'begin'}))
- {
- $content->{'begin'} =~ s/^\s*//;
- #print STDERR "SKIP_SPACES begin\n";
- return if ($content->{'begin'} ne '');
- }
- if (defined($content->{'content'}) or defined($content->{'format_name'})
- or $content->{'definition_line'})
- { # non empty commands stop space skipping, even if they contain
- # only spaces, like @asis{ }
- # also for item(x) that have format_name defined
- #print STDERR "SKIP_SPACES command?\n";
- return;
- }
- if (defined($content->{'text'}))
- {
- my $command = '';
- $command = $content->{'command'} if (defined($content->{'command'}));
- #print STDERR "SKIP_SPACES($command) text\n";
- $content->{'text'} =~ s/^\s*//;
- return if ($content->{'text'} ne '');
- }
- if (defined($content->{'end'}))
- {
- #print STDERR "SKIP_SPACES end\n";
- $content->{'end'} =~ s/^\s*//;
- return if ($content->{'end'} ne '');
- }
- ($current, $index, $close) = ($current_next, $index_next, $close_next);
- }
- }
- sub info_default_store_pending($$;$)
- {
- my $line_char_counter = shift;
- my $pending_spaces_word = shift;
- my $indent_length = shift;
- $indent_length = 0 if (!defined($indent_length));
- my $indent_text = '';
- $indent_text = ' ' x $indent_length;
- #print STDERR "store_pending(spaces `$pending_spaces_word->{'spaces'}', indent($indent_length) `$indent_text' word `".var_to_str($pending_spaces_word->{'word'})."'\n";
- my $result = $pending_spaces_word->{'spaces'};
- $pending_spaces_word->{'spaces'} = '';
- if (defined($pending_spaces_word->{'word'}))
- {
- $result .= $pending_spaces_word->{'word'};
- $pending_spaces_word->{'word'} = undef;
- }
- my $chomped_result = $result;
- chomp ($chomped_result);
- if ($line_char_counter == 0 and $chomped_result ne '')
- {
- $result = $indent_text . $result;
- }
- $line_char_counter += t2h_default_string_width($result);
- return ($line_char_counter, $pending_spaces_word, $result);
- }
- sub info_default_output($)
- {
- my $info_state = shift;
- my $result = '';
- #print STDERR "Storing the stack\n";
- print STDERR "" . Data::Dumper->Dump([$info_state->{'top'}]) if (get_conf('DEBUG'));
- my ($bytes_count, $lines_count);
- ($bytes_count, $result, $lines_count) = info_default_process_content($info_state->{'top'}, $info_state);
- $info_state->{'offset_in_file'} += $bytes_count;
- $info_state->{'line_count'} += $lines_count;
- #print STDERR "HHHHHH($lines_count) $info_state->{'line_count'}: $result\n";
- info_default_reset_state($info_state)
- if (!defined($info_state->{'current'}->{'command'}));
- return $result;
- }
- sub info_default_process_content($$)
- {
- my $current_command = shift;
- my $info_state = shift;
- my $length = 0;
- my $result = '';
- my $line_char_counter = 0;
- my $all_line_passed = 0;
- my $pending_spaces_word;
- $pending_spaces_word->{'spaces'} = '';
- my $preformatted = 0;
- my $indent_level = 0;
- my $item_pending;
- my $in_exdent = 0;
- my $in_para = 0;
- my $in_w = 0;
- my $table_item_line = 0;
- my $in_table_item = 0;
- my $max_column = get_conf('FILLCOLUMN');
- my $direntry = 0;
- my $preformatted_format = 0;
- my $indent_length = 0;
- # for formats that needs to process a full line (center and flushright)
- # to know the line length before outputing
- my $current_line = undef;
- my ($current, $index, $close) = ($current_command, 0, 0);
- #print STDERR "info_default_process_content: $current_command\n";
- while(1)
- {
- last if (!defined($current));
- my $content = $current->{'content'}->[$index];
- my $text_added = '';
- my $line_added_before_item = 0;
- my $indentation_done = 0;
- my $prepend_newline;
- if (get_conf('DEBUG'))
- {
- my $text_item_pending = '';
- $text_item_pending = $item_pending if (defined($item_pending));
- my $text_length = '';
- $text_length = "$content->{'text'}" if defined($content->{'text'});
- my $text_command = '';
- $text_command = $content->{'command'} if defined($content->{'command'});
- my $in_node_count = 0;
- $in_node_count = $info_state->{'line_count'} if defined($info_state->{'line_count'});
- print STDERR "($text_command|$text_length|$close|${all_line_passed}+$in_node_count|l_c_cnt $line_char_counter) prfrmted $preformatted para $in_para indent_lvl $indent_level($indent_length) in_exdent $in_exdent in_w $in_w only_spaces $info_state->{'only_spaces'} blank_line $info_state->{'blank_line'} table_item_line $table_item_line in_table_item $in_table_item item_pending $text_item_pending spaces: `$pending_spaces_word->{'spaces'}' word: ".main::var_to_str($pending_spaces_word->{'word'})."\n";
- }
-
- if ($close)
- {
- if (defined($content->{'end'}))
- {
- $text_added .= $content->{'end'};
- }
- if ($complex_format_map{$content->{'command'}} and $content->{'content'})
- {
- $preformatted_format--;
- }
- # the format is always empty in the main program so the warning
- # has to be done here
- if (defined($content->{'total_item_nr'}) and !$content->{'total_item_nr'} and $content->{'content'})
- {
- main::line_warn (sprintf(__("\@%s has text but no \@item"), $content->{'command'}), $content->{'line_nr'});
- }
- # check whether there is a blank line following, to avoid adding
- # one when closing a format.
- # This is not a required check if not in preformatted since doubled
- # blank lines are discarded.
- my $followed_by_blank_line = 0;
- if ($preformatted_format)
- {
- my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close);
- if (defined($command_next) and $command_next eq 'preformatted')
- {
- ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current_next, $index_next, $close_next);
- $followed_by_blank_line = 1 if (defined($text_next) and $text_next =~ /^\s*$/);
- }
- }
- if ($info_default_indented_commands{$content->{'command'}})
- {
- $indent_level--;
- $indent_length = $indent_level * $info_default_indent_length;
- # $preformatteed cannot be used here since preformatted
- # is closed before the end of a format
- #if ($indent_level > 0 and !$info_state->{'blank_line'} and $content->{'command'} !~ /^deff_item/ and !$preformatted_format)
- if ($indent_level > 0 and !$info_state->{'blank_line'} and $content->{'command'} !~ /^deff_item/ and !$followed_by_blank_line)
- {
- $text_added .= "\n";
- }
- # this nullify a potential noindent in a random format
- $info_state->{'indent_para'} = undef;
- }
- elsif (($complex_format_map{$content->{'command'}} and $content->{'command'} ne 'menu') or $content->{'command'} eq 'cartouche')
- {
- if (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level > 0) and !$followed_by_blank_line)
- {
- $text_added .= "\n";
- }
- }
- if ($content->{'command'} eq 'paragraph' and $info_state->{'align_stack'}->[-1]->{'command'} eq 'normal')
- {
- # if there is no space at the end of a paragraph, there may be
- # pending text, for example, if there is an ending line like
- # Some text@c a comment
- my $pending;
- ($line_char_counter, $pending_spaces_word, $pending) = info_default_store_pending($line_char_counter, $pending_spaces_word, $indent_length);
- $text_added .= $pending if (defined($pending));
- $text_added =~ s/\s*$//;
- $pending_spaces_word->{'spaces'} = '';
- $in_para = 0;
- $info_state->{'indent_para'} = undef;
- $text_added .= "\n" unless (($line_char_counter + t2h_default_string_width($text_added)) == 0);
- }
- elsif ($content->{'command'} eq 'preformatted')
- {
- # if preformatted doesn't end with a newline, it is added here
- $text_added .= "\n" unless ($line_char_counter == 0);
- $preformatted--;
- }
- elsif ($content->{'command'} eq 'menu')
- {
- $text_added .= "\n" unless ($info_state->{'blank_line'});
- }
- elsif ($content->{'command'} eq 'float')
- {
- #$text_added = "\n" . $text_added unless ($info_state->{'blank_line'});
- $prepend_newline = 1 unless ($info_state->{'blank_line'});
- }
- elsif ($content->{'command'} eq 'w')
- {
- $in_w--;
- }
- elsif ($paragraph_style{$content->{'command'}})
- {
- my $popped = pop @{$info_state->{'align_stack'}};
- print STDERR "BUG".main::format_line_number().": align_stack, popped $popped->{'command'} ne command $content->{'command'}\n" if ($popped->{'command'} ne $content->{'command'});
- }
- elsif ($content->{'command'} eq 'multitable')
- {
- my $multitable = pop @{$info_state->{'multitable_stack'}};
- if (!defined($multitable->{'cells'}) and ($result ne ''))
- {
- $multitable->{'result'} .= $result;
- $multitable->{'length'} += $length;
- $multitable->{'line_count'} += $all_line_passed;
- }
- $max_column = $multitable->{'max_column_kept'};
- $result = $multitable->{'result_kept'};
- $line_char_counter = $multitable->{'line_char_counter_kept'};
- $all_line_passed = $multitable->{'all_line_passed_kept'};
- $indent_level = $multitable->{'indent_level_kept'};
- $indent_length = $multitable->{'indent_length_kept'};
- #$indent_length_next_line = undef;
- $length = $multitable->{'length_kept'};
- $info_state->{'offset_in_file'} = $multitable->{'offset_in_file_kept'};
- $info_state->{'line_count'} = $multitable->{'line_count_kept'};
- #print STDERR "MULTITABLE close, lines: $multitable->{'line_count_kept'} + $all_line_passed\n";
- foreach my $anchor_and_index (@{$multitable->{'anchors'}}, @{$multitable->{'index_entries'}})
- {
- $anchor_and_index->{'line_nr'} += $multitable->{'line_count_kept'} + $all_line_passed;
- }
- if (! scalar(@{$info_state->{'multitable_stack'}}))
- {
- #print STDERR "MULTITABLE close, lengths: $multitable->{'offset_in_file_kept'} + $length\n";
- foreach my $anchor (@{$multitable->{'anchors'}})
- {
- $anchor->{'info_offset'} += $multitable->{'offset_in_file_kept'} + $length;
- }
- }
- else
- {
- push @{$info_state->{'multitable_stack'}->[-1]->{'anchors'}}, @{$multitable->{'anchors'}};
- push @{$info_state->{'multitable_stack'}->[-1]->{'index_entries'}}, @{$multitable->{'index_entries'}};
- }
- $text_added .= $multitable->{'result'};
- $indentation_done = 1;
- goto new_text;
- }
- elsif ($content->{'command'} eq 'multitable_cell')
- {
- my $cell = $info_state->{'multitable_stack'}->[-1]->{'cells'}->[-1];
- $cell->{'result'} = $result;
- $cell->{'length'} = $length;
- $cell->{'line_passed'} = $all_line_passed;
- }
- elsif ($content->{'command'} eq 'direntry')
- {
- $direntry--;
- # this has to be done here, otherwise, at the end, $direntry
- # would be 0
- $info_default_dir_specification .= $text_added;
- $text_added = '';
- }
- elsif ($content->{'command'} eq 'multitable_row')
- {
- my $multitable = $info_state->{'multitable_stack'}->[-1];
- my $indent_len = $multitable->{'indent_length_kept'};
- #print STDERR "INDENT: $indent_len\n";
- my $row_length = 0;
- my $row = '';
- my $max_lines = 0;
- my $cell_beginning = 0;
- my @anchor_lines_array;
- my $cell_idx = 0;
- my @anchors;
- my @indices;
- foreach my $cell (@{$multitable->{'cells'}})
- {
- $cell->{'beginning'} = $cell_beginning;
- $cell_beginning += $cell->{'cell_width'}+1;
- @{$cell->{'lines'}} = split /^/, $cell->{'result'};
- $max_lines = scalar(@{$cell->{'lines'}}) if (scalar(@{$cell->{'lines'}}) > $max_lines);
- foreach my $anchor (@{$cell->{'anchors'}})
- {
- push @{$anchor_lines_array[$anchor->{'line_nr'}]}, $anchor;
- $anchor->{'cell_idx'} = $cell_idx;
- push @anchors, $anchor;
- }
- push @indices, @{$cell->{'index_entries'}};
- $cell_idx++;
- }
- my $previous_last_cell = scalar(@{$multitable->{'cells'}});
- #print STDERR "ROW cell_beginning $cell_beginning, max_lines $max_lines, previous_last_cell $previous_last_cell\n";
- for (my $line_idx = 0; $line_idx < $max_lines; $line_idx++)
- {
- my $line_width = $indent_len;
- my $line_bytes = info_default_byte_count(' ' x$indent_len);
- my $line = '';
- # determine the last cell in the line, to fill spaces in
- # cells preceding that cell on the line
- my $last_cell = 0;
- for (my $cell_idx = 0; $cell_idx < $previous_last_cell; $cell_idx++)
- {
- $last_cell = $cell_idx+1 if (defined($multitable->{'cells'}->[$cell_idx]->{'lines'}->[$line_idx]));
- }
- #print STDERR " L(last_cell $last_cell): $line_idx\n";
- for (my $cell_idx = 0; $cell_idx < $last_cell; $cell_idx++)
- {
- my $cell_text = $multitable->{'cells'}->[$cell_idx]->{'lines'}->[$line_idx];
- #print STDERR " C($cell_idx) ";
- if (defined($cell_text))
- {
- chomp($cell_text);
- #print STDERR "$cell_text";
- if ($line eq '' and $cell_text ne '')
- {
- $line = ' ' x $indent_len;
- }
- $line .= $cell_text;
- $line_width += t2h_default_string_width($cell_text);
- $line_bytes += info_default_byte_count($cell_text);
- }
- if ($cell_idx+1 < $last_cell)
- {
- if ($line_width < $indent_len + $multitable->{'cells'}->[$cell_idx+1]->{'beginning'})
- {
- if ($line eq '')
- {
- $line = ' ' x $indent_len;
- }
- my $spaces = ' ' x ($indent_len + $multitable->{'cells'}->[$cell_idx+1]->{'beginning'} - $line_width);
- $line_width += t2h_default_string_width($spaces);
- $line_bytes += info_default_byte_count($spaces);
- $line .= $spaces;
- #print STDERR " Csp($line_width) `$spaces'";
- }
- }
- }
- if (defined($anchor_lines_array[$line_idx]))
- {
- foreach my $anchor (@{$anchor_lines_array[$line_idx]})
- {
- my $anchor_position = $indent_len + $anchor->{'line_char_counter'} + $multitable->{'cells'}->[$anchor->{'cell_idx'}]->{'beginning'};
- if ($anchor_position > $line_width)
- {
- my $spaces = ' ' x ($anchor_position - $line_width);
- $line .= $spaces;
- $line_width += t2h_default_string_width($spaces);
- $line_bytes += info_default_byte_count($spaces);
- }
- $anchor->{'info_offset'} = $line_bytes + $row_length + $multitable->{'length'};
- #print STDERR "ROW anchor close: anchor[$anchor->{'cell_idx'}]($multitable->{'cells'}->[$anchor->{'cell_idx'}]->{'beginning'}+$anchor->{'line_char_counter'}) $anchor_position $anchor->{'info_offset'}\n";
- $anchor->{'line_char_counter'} = $anchor_position;
- }
- }
- $line .= "\n";
- $row_length += info_default_byte_count($line);
- #print STDERR " ($line_width,".length($line).") $line";
- $row .= $line;
- $previous_last_cell = $last_cell;
- }
- foreach my $anchor_and_index (@anchors, @indices)
- {
- $anchor_and_index->{'line_nr'} += $multitable->{'line_count'};
- #print STDERR "ROW close: new line count: $anchor_and_index->{'line_nr'} + \n";
- }
- if ($content->{'item_command'} eq 'headitem')
- {
- # at this point cell_beginning is at the beginning of
- # the cell following the end of the table -> full width
- my $line = ' ' x $indent_len . '-' x $cell_beginning . "\n";
- $row .= $line;
- $row_length += info_default_byte_count($line);
- }
- #print STDERR "ROW_LENGTH $row_length\n";
- $multitable->{'result'} .= $row;
- $multitable->{'length'} += $row_length;
- $multitable->{'line_count'} += $max_lines;
- $multitable->{'cells'} = [];
- push @{$multitable->{'anchors'}}, @anchors;
- push @{$multitable->{'index_entries'}}, @indices;
- }
- }
- else
- {
- if ($content->{'command'})
- {
- # if processing a paragraph, there may be some pending text
- # and spaces, as the idea is to write them down only when
- # there is a space in case of pending text, or when there is some
- # text in case of pending space. So all the commands
- # that should write something within paragraph must flush the
- # pending text/spaces _before_ they output something, or the
- # text order will be reversed, with the pending things output
- # after the other commands text.
- my $pending_added_length = 0;
- my $pending_added_bytes = 0;
- if ($content->{'command'} eq 'anchor' or $content->{'command'} eq 'image' or $content->{'command'} eq 'index_command' or $content->{'command'} eq 'sp' or $content->{'raw_command'})
- {
- my $pending;
- ($line_char_counter, $pending_spaces_word, $pending) = info_default_store_pending($line_char_counter, $pending_spaces_word, $indent_length);
- # here spaces out of any environment are ignored.
- if ($in_para or $preformatted or $pending =~ /\S/)
- { # this has to be done before the anchor related code
- # to have the right count.
- # FIXME this is wrong if an end of line was passed.
- # in that case line_char_counter has been increased and
- # $pending ends with an end of line
- $pending_added_length += t2h_default_string_width($pending);
- $pending_added_bytes += info_default_byte_count($pending);
- $text_added .= $pending;
- }
- }
- if ($content->{'command'} eq 'strong')
- {
- my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close);
- if (defined($text_next) and $text_next =~ /^Note\b/i)
- {
- main::line_warn(__("\@strong{Note...} produces a spurious cross-reference in Info; reword to avoid that"), $content->{'line_nr'});
- }
- }
- elsif ($content->{'command'} eq 'w')
- {
- $in_w++ if ($content->{'content'});
- }
- elsif ($content->{'command'} eq 'anchor' or ($content->{'command'} eq 'float' and $content->{'anchor_reference'}))
- {
- #print STDERR "anchor: offset_in_file $info_state->{'offset_in_file'}, line_count $info_state->{'line_count'}, line_char_counter $line_char_counter pending_added_length $pending_added_length\n";
- $content->{'anchor_reference'}->{'info_offset'} = $length + $info_state->{'offset_in_file'} + $pending_added_bytes;
- $content->{'anchor_reference'}->{'line_nr'} = $all_line_passed + $info_state->{'line_count'};
- $content->{'anchor_reference'}->{'line_char_counter'} = $line_char_counter + $pending_added_length;
- if (@{$info_state->{'multitable_stack'}})
- {
- if ($info_state->{'multitable_stack'}->[-1]->{'cells'})
- {
- push @{$info_state->{'multitable_stack'}->[-1]->{'cells'}->[-1]->{'anchors'}}, $content->{'anchor_reference'};
- }
- else
- {
- push @{$info_state->{'multitable_stack'}->[-1]->{'anchors'}}, $content->{'anchor_reference'};
- }
- }
- push @{$info_state->{'pending_tags'}}, $content->{'anchor_reference'};
- push @{$info_state->{'align_stack'}->[-1]->{'anchors'}}, $content->{'anchor_reference'} if ($info_state->{'align_stack'}->[-1]->{'command'} eq 'center' or $info_state->{'align_stack'}->[-1]->{'command'} eq 'flushright');
- }
- elsif ($content->{'command'} eq 'index_label')
- {
- #print STDERR "FFFFFFFFF($content->{'index_command'}) $all_line_passed + $info_state->{'line_count'} `$content->{'texi_entry'}'\n";
- my $index_line_nr = $all_line_passed + $info_state->{'line_count'};
- if ($info_state->{'blank_line'} and $content->{'index_command'} =~ /index$/)
- {
- my ($current_next, $index_next, $close_next) = info_default_iterator_next($current, $index, $close);
- $index_line_nr-- if (!defined($current_next));
- }
- elsif ($content->{'index_command'} =~ /^[vf]table$/)
- {
- # if in a table, index label is systematically entered after
- # the line is processed, as the line is processed with the
- # item command, while the index entry is entered with the
- # index_label callback that is done much later.
- $index_line_nr--;
- }
- #print STDERR "index in a blank_line $content->{'index_command'} `$content->{'texi_entry'}'\n" if ($info_state->{'blank_line'});
- my $index_name = $content->{'index_entry_reference'}->{'index_name'};
- $info_default_index_line_string_length{$index_name} = t2h_default_string_width($index_line_nr)
- if (!defined($info_default_index_line_string_length{$index_name}) or $info_default_index_line_string_length{$index_name} < t2h_default_string_width($index_line_nr));
- #print STDERR "RRRRRRRRRRRRR($content->{'index_entry_reference'}) $content->{'index_entry_reference'}->{'texi'} name: $index_name line: $index_line_nr max: $info_default_index_line_string_length{$index_name}\n";
- my $index_ref = { 'index_entry_reference' => $content->{'index_entry_reference'}, 'line_nr' => $index_line_nr };
- #print STDERR "INDEX($index_name) line $index_line_nr\n";
- $info_default_index_entries{$content->{'index_entry_reference'}} = $index_ref;
- # there may be no cell in case of an empty multitable
- if (@{$info_state->{'multitable_stack'}})
- {
- if ($info_state->{'multitable_stack'}->[-1]->{'cells'})
- {
- push @{$info_state->{'multitable_stack'}->[-1]->{'cells'}->[-1]->{'index_entries'}}, $index_ref;
- }
- else
- {
- push @{$info_state->{'multitable_stack'}->[-1]->{'index_entries'}}, $index_ref;
- }
- }
- push @{$info_state->{'pending_index_entries'}}, $index_ref;
- }
- elsif ($content->{'command'} eq '*' and !$preformatted)
- {
- if (defined($pending_spaces_word->{'word'}))
- {
- $text_added .= $pending_spaces_word->{'spaces'} . $pending_spaces_word->{'word'};
- $pending_spaces_word->{'word'} = undef;
- }
- # spaces preceding @* are skipped
- $pending_spaces_word->{'spaces'} = '';
- $text_added .= $content->{'text'};
- # just like following spaces
- info_default_skip_spaces($current, $index, $close);
- # this isn't done otherwise, though, here it is not important
- # since this end the line
- $line_char_counter += t2h_default_string_width($content->{'text'});
- goto new_text;
- }
- elsif ($content->{'command'} eq 'paragraph' and $info_state->{'align_stack'}->[-1]->{'command'} eq 'normal')
- {
- # empty paragraph
- goto new_text if (!$content->{'content'});
- my $paragraphindent = get_conf('paragraphindent');
- $paragraphindent = 0 if ($paragraphindent eq 'none');
- if ($paragraphindent ne 'asis')
- {
- info_default_skip_spaces($current, $index, $close);
- }
- # if within a format $content->{'paragraph_in_element_nr'}
- # should not be defined so no indentation will take place
- if ($paragraphindent ne 'asis' and $paragraphindent and $line_char_counter == 0 and (defined($content->{'paragraph_in_element_nr'})) and ($info_state->{'indent_para'} or (!defined($info_state->{'indent_para'}) and ($content->{'paragraph_in_element_nr'} or (get_conf('firstparagraphindent') eq 'insert')))))
- {
- $text_added .= ' ' x $paragraphindent;
- }
- $in_para = 1;
- }
- elsif ($content->{'command'} eq 'preformatted')
- {
- $preformatted++ if ($content->{'content'});
- }
- elsif ($content->{'command'} eq 'exdent')
- {
- # if an end of line is added, in_exdent is set to 2 and
- # set to one when processing the end of line that was just
- # added, and set to 0 at the end of the line.
- # if there is no end of line added, it is only set to 1.
- if ($line_char_counter != 0)
- {
- $text_added .= "\n";
- $in_exdent = 2;
- }
- else
- {
- $in_exdent = 1;
- }
- $indent_length = ($indent_level -1) * $info_default_indent_length if ($indent_level > 0);
- #goto new_text;
- }
- elsif ($content->{'command'} eq 'indent')
- {
- $info_state->{'indent_para'} = 1;
- }
- elsif ($content->{'command'} eq 'noindent')
- {
- $info_state->{'indent_para'} = 0;
- }
- elsif ($content->{'command'} eq 'sp')
- {
- $text_added .= $content->{'text'};
- goto new_text;
- }
- elsif ($content->{'command'} eq 'image')
- {
- # @image result count isn't counted in line_char_counter
- # since it is not displayed in info
- my $indent_added = 0;
- $indent_added = ($indent_length - $line_char_counter) if ($indent_length - $line_char_counter > 0);
- $text_added .= ' ' x $indent_added . $content->{'text'};
- $line_char_counter += $indent_added;
- goto new_text;
- }
- elsif ($content->{'command'} eq 'ref')
- { # adds a . if needed.
- if ($content->{'text'} !~ /[\.,]$/ and $content->{'text'} !~ /::$/)
- {
- my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close);
- if (!defined($text_next) or $text_next !~ /^[\.,]/)
- {
- $content->{'text'} .= '.';
- }
- }
- }
- elsif ($content->{'command'} eq 'xref')
- { # warn if there is no punctuation following
- my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close);
- if (!defined($text_next) or $text_next !~ /^./)
- { # in makeinfo it is
- # "End of file reached while looking for `.' or `,'"
- # but maybe it may not be true.
- main::line_warn(__("`.' or `,' must follow \@xref."), $Texi2HTML::THISDOC{'line_nr'});
- }
- elsif ($text_next !~ /^[\.,]/)
- {
- my $char = substr($text_next, 0, 1);
- main::line_warn(sprintf(__("`.' or `,' must follow \@xref, not %s"), $char), $Texi2HTML::THISDOC{'line_nr'});
- }
- }
- elsif ($content->{'definition_line'})
- {
-
- my $dummy_line_passed;
- print STDERR "BUG: defined pending_word before DEFINITION_LINE\n" if defined($pending_spaces_word->{'word'});
- #print STDERR "DEFINITION_LINE($line_char_counter,$pending_spaces_word->{'spaces'},$indent_length,$in_para,$max_column): $content->{'text'}";
- ($line_char_counter, $pending_spaces_word, $dummy_line_passed, $text_added) = info_default_process_para_text($content->{'text'}, $line_char_counter, $pending_spaces_word, $indent_length, $max_column, 0, $indent_length+2*$info_default_indent_length);
- $text_added .= $pending_spaces_word->{'spaces'};
- $pending_spaces_word->{'spaces'} = '';
- #print STDERR "DEFINITION_LINE($line_char_counter,$pending_spaces_word->{'spaces'}) -> $text_added";
- print STDERR "BUG: defined pending_word after DEFINITION_LINE\n" if defined($pending_spaces_word->{'word'});
- $indentation_done = 1;
-
- goto new_text;
- }
- elsif (($content->{'command'} eq 'item' or $content->{'command'} eq 'itemx') and exists $info_default_indent_format_length{$content->{'format_name'}})
- {
- $item_pending = $content->{'format_name'};
- #if (!$info_state->{'blank_line'} and $content->{'command'} eq 'item')
- my $first_item = 0;
-
- if ($content->{'command'} eq 'item')
- {
- if (!defined($content->{'parent'}->{'item_nr'}))
- {
- $content->{'parent'}->{'item_nr'} = 1;
- $first_item = 1;
- }
- else
- {
- $content->{'parent'}->{'item_nr'}++;
- }
- }
- if ($item_pending =~ /table$/)
- {
- $table_item_line = 1;
- $indent_length = ($indent_level -1) * $info_default_indent_length if ($indent_level > 0);
- $in_table_item = 0;
- }
- else
- {
- $indent_length = ($info_default_indent_format_length{$item_pending}
- +($indent_level -1)* $info_default_indent_length);
- }
- if (!$info_state->{'blank_line'} and ($content->{'command'} ne 'itemx') and (!$first_item or $indent_level > 1))
- {
- my $dummy_line_passed;
- ($line_char_counter, $dummy_line_passed, $text_added) = info_default_process_line_text($text_added, $line_char_counter, $indent_length);
- $indentation_done = 1;
- $line_added_before_item = 1;
- $prepend_newline = 1;
- #$text_added = "\n" . $text_added;
- }
-
- if ($item_pending =~ /table$/)
- {
- # one less indentation level and no line break
- # adding line_added_before_item allows the table_item_line to
- # still be active after the additional blank line
- $table_item_line = 1+$line_added_before_item;
- }
- else
- {
- info_default_skip_spaces($current, $index, $close);
- }
- }
- elsif ($content->{'command'} eq 'menu' or $content->{'command'} eq 'listoffloats' or $content->{'heading_command'})
- {
- $text_added .= "\n" unless ($info_state->{'blank_line'});
- }
- elsif ($content->{'command'} eq 'direntry')
- {
- if ($content->{'content'})
- {
- $direntry++;
- }
- }
- elsif ($paragraph_style{$content->{'command'}})
- {
- goto new_text if (!$content->{'content'});
- push @{$info_state->{'align_stack'}}, {'command' => $content->{'command'}};
- }
- elsif ($content->{'command'} eq 'verbatim' or $content->{'command'} eq 'verbatiminclude')
- {
- # $preformatted cannot be used here since preformatted
- # is closed before a verbatim, $preformatted_format is used
- if (!$preformatted_format and $indent_level != 0)
- {
- if (!$info_state->{'blank_line'} and $info_state->{'only_spaces'})
- {
- $text_added .= "\n";
- }
- my $verb_text = $content->{'text'};
- my ($line_passed, $end_of_line, $last_line, $text_indented, $blank_line) = info_default_count_lines($verb_text);
- $content->{'text'} .= "\n" unless ($blank_line or ($last_line =~ /^\s*$/));
- }
- }
- # other raw commands
- elsif ($content->{'raw_command'})
- {
- # not considered as in a paragraph even if in a paragraph
- $text_added .= $content->{'text'};
- goto new_text;
- }
- elsif ($content->{'command'} eq 'multitable' and $content->{'content'})
- {
- my $indent_length_kept = $indent_level * $info_default_indent_length;
- my $multitable = {
- 'offset_in_file_kept' => $info_state->{'offset_in_file'},
- 'line_count_kept' => $info_state->{'line_count'},
- 'columns_size' => [ @{$content->{'columns_size'}} ],
- 'result' => '',
- 'length' => 0,
- 'line_count' => 0,
- 'result_kept' => $result,
- 'length_kept' => $length,
- 'all_line_passed_kept' => $all_line_passed,
- 'line_char_counter_kept' => $line_char_counter,
- 'max_column_kept' => $max_column,
- 'indent_level_kept' => $indent_level,
- 'indent_length_kept' => $indent_length_kept,
- };
- push @{$info_state->{'multitable_stack'}}, $multitable;
- $info_state->{'offset_in_file'} = 0;
- $info_state->{'line_count'} = 0;
- $result = '';
- $length = 0;
- $all_line_passed = 0;
- $line_char_counter = 0;
- $indent_level = 0;
- $indent_length = 0;
- }
- elsif ($content->{'command'} eq 'multitable_row')
- {
- my $multitable = $info_state->{'multitable_stack'}->[-1];
- if (!defined($multitable->{'cells'}) and ($result ne ''))
- {
- $multitable->{'result'} .= $result;
- $multitable->{'length'} += $length;
- $multitable->{'line_count'} += $all_line_passed;
- $multitable->{'cells'} = [];
- }
- $multitable->{'cell_index'} = -1;
- }
- elsif ($content->{'command'} eq 'multitable_cell')
- {
- my $multitable = $info_state->{'multitable_stack'}->[-1];
- $multitable->{'cell_index'}++;
- my $cell_width = $content->{'parent'}->{'parent'}->{'columns_size'}->[$multitable->{'cell_index'}];
- #$max_column = $cell_width-1;
- $max_column = $cell_width -2;
- my $cell = {'cell_width' => $cell_width, 'index_entries' => [], 'anchors' => []};
- push @{$multitable->{'cells'}}, $cell;
- $result = '';
- $length = 0;
- $all_line_passed = 0;
- $line_char_counter = 0;
- $indent_level = 0;
- $indent_length = 0;
- if (!$content->{'content'})
- {# empty cell
- $cell->{'result'} = $result;
- $cell->{'length'} = $length;
- $cell->{'line_passed'} = $all_line_passed;
- }
- #info_default_skip_spaces($current, $index, $close);
- }
- if ($info_default_indented_commands{$content->{'command'}})
- {
- if ($content->{'command'} =~ /^deff_item/)
- {
- info_default_skip_spaces($current, $index, $close);
- }
- #elsif (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level != 0) and !$preformatted)
- elsif (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level != 0))
- {
- $text_added .= "\n";
- }
- # there is no close if !$content->{'content'}
- $indent_level++ if ($content->{'content'});
- $indent_length = $indent_level * $info_default_indent_length;
- }
- elsif (($complex_format_map{$content->{'command'}} and $content->{'command'} ne 'menu') or $content->{'command'} eq 'cartouche')
- {
- #if (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level != 0) and !$preformatted_format)
- if (!$info_state->{'blank_line'} and $info_state->{'only_spaces'} and ($indent_level != 0))
- {
- $text_added .= "\n";
- }
- }
- if ($complex_format_map{$content->{'command'}} and $content->{'content'})
- {
- $preformatted_format++;
- }
- }
- if (defined($content->{'text'}))
- {
- if ($in_para and !$in_exdent)
- {
- #print STDERR "IN_PARA text\n";
- my $new_text = $content->{'text'};
- # first find if in a context of no puncutation related
- # modification: code style command or @var, @cite, @math
- # acceptable for punctuation related modifications:
- # asis b dfn emph i slanted sansserif r sc strong t w
- my $current_tested = $content;
- my $no_punctation_munging_command;
- while ($current_tested)
- {
- if (defined($current_tested->{'command'}) and (($style_map{$current_tested->{'command'}} and $style_map{$current_tested->{'command'}}->{'args'} and $style_map{$current_tested->{'command'}}->{'args'}->[0] and $style_map{$current_tested->{'command'}}->{'args'}->[0] eq 'code') or $current_tested->{'command'} eq 'var' or $current_tested->{'command'} eq 'cite' or $current_tested->{'command'} eq 'math'))
- {
- $no_punctation_munging_command = 1;
- last;
- }
- $current_tested = $current_tested->{'parent'};
- }
- # a punctuation at the end of line in a command is treated
- # like a punctuation in plain text, except for @:,
- # accent commands, @dots, 'simple_style' command, and if in
- # a command as found out just above.
- if (!$no_punctation_munging_command and (!defined($content->{'command'}) or ($content->{'command'} ne ':' and $content->{'command'} ne 'accents_commands' and $content->{'command'} ne 'dots') and !$info_default_leaf_command{$content->{'command'}}) and get_conf('frenchspacing') ne 'on' and $new_text =~ /([$info_default_end_sentence_character])([$info_default_after_punctuation_characters]*)(\s*)$/)
- {
- my $spaces = $3;
- if (chomp($new_text))
- {
- $new_text =~ s/(\s*)$/ /;
- }
- else
- {
- # these variables hold the place where the end
- # of line characters are normalized.
- my ($current_start_from, $index_start_from, $close_start_from) = ($current, $index, $close);
- my $only_after_punctuation_characters = 1;
- my $spaces_to_normalize = 0;
- # first find whether there are only
- # after_punctuation_characters followed by spaces
- # and find the place where the
- # after_punctuation_characters end
- my ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current, $index, $close);
- # go through the text as long as there are after_punctuation_characters
- if (!$spaces)
- {
- while (1)
- {
- # !defined($text_next) catches many special
- # commands, like anchor, index. Not sure if
- # it is right or wrong.
- # Also a style_map command never stops
- # the search, so that @emph{ or @strong{
- # begin and end are not taken into account
- if (!defined($current_next) or (!defined($text_next)) or (defined($command_next) and $command_next eq '*') or ($text_next !~ /^[$info_default_after_punctuation_characters]*(\s*)$/ and (!defined($command_next) or !$style_map{$command_next})))
- {
- $only_after_punctuation_characters = 0;
- last;
- }
- my $text_next_kept = $text_next;
- # begin normalizing spaces at the last place
- # where there are after_punctuation_characters
- $current_start_from = $current_next;
- $index_start_from = $index_next;
- $index_start_from = $index_next;
- ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current_next, $index_next, $close_next);
- if ($text_next_kept =~ /^[$info_default_after_punctuation_characters]*\s+$/)
- {
- if (chomp($text_next_kept))
- {
- $spaces_to_normalize = 1;
- }
- last;
- }
- }
- }
- # check if there are only spaces until end of line
- if ($only_after_punctuation_characters and !$spaces_to_normalize)
- {
- while (1)
- {
- # !defined($text_next) catches many special
- # commands, like anchor, index. Not sure if
- # it is right or wrong.
- last if (!defined($current_next) or (!defined($text_next)) or (defined($command_next) and $command_next eq '*'));
- if ($text_next =~ /\S/ and (!defined($command_next) or !$style_map{$command_next}))
- {
- last;
- }
- else
- {
- if (chomp($text_next))
- {
- $spaces_to_normalize = 1;
- last;
- }
- }
- ($current_next, $index_next, $close_next, $text_next, $command_next) = info_default_next ($current_next, $index_next, $close_next);
- }
-
- }
- if ($spaces_to_normalize)
- {
- # now do the spaces normalization
- info_default_skip_spaces($current_start_from, $index_start_from, $close_start_from);
- my $content = $current_start_from->{'content'}->[$index_start_from];
- $content->{'text'} =~ s/(\s*)$/ /;
- }
- }
- }
- elsif (chomp($new_text))
- {
- $new_text =~ s/(\s*)$/ /;
- }
- $text_added .= $new_text;
- } # ignore spaces outside of paragraphs and preformatted
- elsif ($preformatted or $info_state->{'align_stack'}->[-1]->{'command'} ne 'normal')
- {
- #print STDERR "IN_PREFORMATTED or ALIGN text\n";
- $text_added .= $content->{'text'};
- }
- else
- {
- my $chomped_text = $content->{'text'};
- if ($chomped_text !~ /\S/ and chomp($chomped_text) and !$item_pending)
- {
- if ($in_table_item and $info_state->{'only_spaces'})
- {
- # in a blank_line
- #print STDERR "IN_ITEM ignored: `$content->{'text'}'\n";
- }
- elsif (!$info_state->{'blank_line'} or !$info_state->{'only_spaces'})
- {
- #print STDERR "IN_ADDING_BLANK_LINE because no line before or text before\n";
- $text_added .= "\n";
- }
- else
- {
- #print STDERR "IN_NOT_ADDING_BLANK_LINE\n";
- }
- }
- else
- { # exdent, item not in paragraph nor in preformatted
- #print STDERR "NOWHERE and not end of line (or item_pending) `$content->{'text'}'\n";
- $text_added .= $content->{'text'};
- }
- }
- }
- else
- {
- if (defined($content->{'begin'}))
- {
- $text_added .= $content->{'begin'};
- }
- # command that won't be closed, so the end has to be added
- # here. It should mostly happen for empty style @-commands.
- if (defined($content->{'end'}) and !defined($content->{'content'}))
- {
- $text_added .= $content->{'end'};
- }
- }
- }
- if (!$preformatted and !$in_exdent and $info_state->{'align_stack'}->[-1]->{'command'} eq 'normal' and $in_para)
- {
- # the line_passed returned here are not used, since they are computed
- # below.
- $indentation_done = 1;
- my $dummy_line_passed;
- ($line_char_counter, $pending_spaces_word, $dummy_line_passed, $text_added) = info_default_process_para_text($text_added, $line_char_counter, $pending_spaces_word, $indent_length, $max_column, $in_w, $indent_level * $info_default_indent_length) if ($text_added ne '');
- }
- elsif ($info_state->{'align_stack'}->[-1]->{'command'} ne 'center' and $info_state->{'align_stack'}->[-1]->{'command'} ne 'flushright')
- {
- my $dummy_line_passed;
- ($line_char_counter, $dummy_line_passed, $text_added) = info_default_process_line_text($text_added, $line_char_counter, $indent_length);
- #$indentation_done = 1;
- }
- else
- {
- $line_char_counter += t2h_default_string_width($text_added);
- }
- new_text:
- if ($text_added ne '')
- {
- if ($item_pending and !$line_added_before_item)
- {
- #info_default_skip_spaces($current, $index, $close);
- $item_pending = undef;
- }
- }
- if ($text_added =~ /\S/)
- {
- $in_table_item = 0 if ($in_table_item);
- $info_state->{'blank_line'} = 0;
- }
- $text_added = "\n" . $text_added if ($prepend_newline);
- print STDERR "TEXT_ADDED($indent_length) `$text_added'\n" if ($text_added ne '' and get_conf('DEBUG'));
- #print STDERR "TEXT_ADDED($indent_length) `$text_added'\n";
- # from here, the next cmmand is available
- ($current, $index, $close) = info_default_iterator_next($current, $index, $close);
- my ($line_passed, $end_of_line, $last_line, $text_indented, $blank_line) = info_default_count_lines($text_added, $indent_length, ($indentation_done
- or $info_state->{'align_stack'}->[-1]->{'command'} eq 'center'
- or $info_state->{'align_stack'}->[-1]->{'command'} eq 'flushright'));
- $info_state->{'blank_line'} = 1 if ($blank_line);
- print STDERR "ADDING `$text_indented'\n" if ($text_indented ne '' and get_conf('DEBUG'));
- # only_space is set in all the conditionals
- if ($end_of_line)
- {
- $line_char_counter = 0;
- if ($in_exdent)
- {
- $in_exdent--;
- }
- if ($table_item_line)
- {
- $table_item_line--;
- $in_table_item = 1;
- }
- if (!$table_item_line and !$in_exdent and !$item_pending)
- {
- $indent_length = $indent_level * $info_default_indent_length;
- }
- $info_state->{'blank_line'} = 1 if ($info_state->{'only_spaces'} and ($last_line !~ /\S/));
- $info_state->{'only_spaces'} = 1;
- }
- else
- {
- if ($line_passed)
- {# in that case we added more than one line, the $line_char_counter
- # is reset to the last line length.
- $line_char_counter = t2h_default_string_width($last_line);
- $in_exdent = 0;
- $indent_length = $indent_level * $info_default_indent_length;
- if ($last_line !~ /\S/)
- {
- $info_state->{'only_spaces'} = 1;
- }
- else
- {
- $info_state->{'only_spaces'} = 0;
- }
- }
- else
- {
- $info_state->{'only_spaces'} = 0 if ($last_line =~ /\S/);
- }
- }
- if ($info_state->{'align_stack'}->[-1]->{'command'} eq 'center'
- or $info_state->{'align_stack'}->[-1]->{'command'} eq 'flushright')
- {
- if (defined($current_line))
- {
- $text_added = $current_line . $text_added;
- }
- $text_indented = '';
- $current_line = undef;
- my $spaces_prepended = undef;
- foreach my $line (split /^/, $text_added)
- {
- my $chomped_line = $line;
- if (chomp($chomped_line))
- {
- $line =~ s/^\s*//;
- $line =~ s/\s*$//;
-
- if (t2h_default_string_width($line) eq 0)
- {
- $spaces_prepended = 0;
- $text_indented .= "\n";
- }
- else
- {
- my $line_width = t2h_default_string_width($line);
- if ($line_width > $max_column)
- {
- $spaces_prepended = 0;
- }
- elsif ($info_state->{'align_stack'}->[-1]->{'command'} eq 'center')
- {
- $spaces_prepended = (($max_column -1 - $line_width) /2);
- }
- else
- {
- $spaces_prepended = ($max_column -1 - $line_width);
- }
- $text_indented .= ' ' x$spaces_prepended . $line ."\n";
- }
- }
- else
- {
- $current_line = $line;
- }
- }
- if (defined ($spaces_prepended) and defined($info_state->{'align_stack'}->[-1]->{'anchors'}))
- {
- while (@{$info_state->{'align_stack'}->[-1]->{'anchors'}})
- {
- my $anchor = shift @{$info_state->{'align_stack'}->[-1]->{'anchors'}};
- $anchor->{'info_offset'} += info_default_byte_count(' ' x$spaces_prepended);
- }
- }
- }
-
- if ($direntry)
- {
- $info_default_dir_specification .= $text_indented;
- }
- else
- {
- $result .= $text_indented;
- $length += info_default_byte_count($text_indented);
- $all_line_passed += $line_passed;
- }
- }
- return ($length, $result, $all_line_passed);
- }
- sub info_default_open_command($$;$)
- {
- my $state = shift;
- my $command = shift;
- my $additional_entries = shift;
- my $index = 0;
-
- my $info_state = info_default_get_state($state);
- # index in the parent content list
- $index = scalar(@{$info_state->{'current'}->{'content'}})
- if (defined($info_state->{'current'}->{'content'}));
- my $new_command = {'command' => $command, 'parent' => $info_state->{'current'}, 'index_in_parent' => $index };
- if (defined($additional_entries))
- {
- foreach my $key (keys(%$additional_entries))
- {
- $new_command->{$key} = $additional_entries->{$key};
- }
- }
- push @{$info_state->{'current'}->{'content'}}, $new_command;
- $info_state->{'current'} = $new_command;
- print STDERR "TREE($info_state->{'nr'}): Opened $command\n" if (get_conf('DEBUG'));
- }
- sub info_default_close_command($$;$$$)
- {
- my $state = shift;
- my $command = shift;
- my $begin = shift;
- my $end = shift;
- my $command_entries = shift;
- $state = $Texi2HTML::THISDOC{'state'} if (!defined($state));
- my $info_state = info_default_get_state($state);
- print STDERR "TREE($info_state->{'nr'}): Closing $command\n" if (get_conf('DEBUG'));
- if (!defined($info_state->{'current'}))
- {
- print STDERR "info_state->{'current'} not defined (closing $command)\n";
- }
- elsif (!defined($info_state->{'current'}->{'command'}))
- {
- print STDERR "info_state->{'current'}->{'command'} not defined (closing $command)\n";
- }
- elsif ($command ne $info_state->{'current'}->{'command'})
- {
- print STDERR "Was waiting for $info_state->{'current'}->{'command'} (closing $command)\n";
- }
- #return if $no_close;
- $command_entries->{'begin'} = $begin;
- $command_entries->{'end'} = $end;
- $command_entries->{'line_nr'} = $Texi2HTML::THISDOC{'line_nr'};
- foreach my $key (keys(%$command_entries))
- {
- $info_state->{'current'}->{$key} = $command_entries->{$key}
- if (defined($command_entries->{$key}));
- }
- $info_state->{'current'} = $info_state->{'current'}->{'parent'};
- return info_default_output($info_state)
- if (!defined($info_state->{'current'}->{'command'}));
- return '';
- }
- sub info_default_store_text($$;$$)
- {
- my $state = shift;
- my $text = shift;
- my $command = shift;
- my $text_entries = shift;
- $state = $Texi2HTML::THISDOC{'state'} if (!defined($state));
- my $info_state = info_default_get_state($state);
- return '' if ((!defined($text) or $text eq '') and !defined($command));
- ################################## debug
- my $command_text = '';
- $command_text = "\[$command\]" if (defined($command));
- $command_text .= $text if (defined($text));
- print STDERR "TREE($info_state->{'nr'}) Storing: ${command_text}\n" if (get_conf('DEBUG'));
- ################################## end debug
- $text_entries->{'text'} = $text if (defined($text));
- $text_entries->{'command'} = $command if (defined($command));
- $text_entries->{'parent'} = $info_state->{'current'};
- $text_entries->{'line_nr'} = $Texi2HTML::THISDOC{'line_nr'};
- push @{$info_state->{'current'}->{'content'}}, $text_entries;
- return info_default_output($info_state)
- if (!defined($info_state->{'current'}->{'command'}));
- return '';
- }
- sub info_default_increment_paragraph ($$$;$)
- {
- my $in_format = shift;
- my $parent_format = shift;
- my $info_state = shift;
- my $command = shift;
- if ($in_format)
- {
- $parent_format->{'paragraph_in_format_nr'} = 0 if (!defined($parent_format->{'paragraph_in_format_nr'}));
- $parent_format->{'paragraph_in_format_nr'}++;
- }
- else
- {
- $info_state->{'paragraph_in_element_nr'}++;
- }
- ####################### debug
- $command = 'PARA' if (!defined($command));
- if (0)
- #if (1)
- {
- my $format_info = '';
- if ($in_format)
- {
- $format_info = "format: [$parent_format->{'command'}],$parent_format->{'paragraph_in_format_nr'}"
- }
- print STDERR "INCREMENT_PARA($command) $info_state->{'paragraph_in_element_nr'} $format_info\n";
- }
- ####################### end debug
- }
- sub info_default_begin_format_texi($$$)
- {
- my $command = shift;
- my $line = shift;
- my $state = shift;
- my $info_state = info_default_get_state ($state);
- my ($parent_format, $in_format);
- ($parent_format, $in_format) = info_default_parent_format($info_state->{'current'});
- info_default_increment_paragraph ($in_format, $parent_format, $info_state, $command);
- # remove space in front of center, unless it removes the end of line!
- $line =~ s/^\s*// if ($command eq 'center' and $line =~ /\S/);
- # don't open a format if it is a @def*x command and we are already in the
- # corresponding @def* command
- info_default_open_command($state,$command) unless ($def_map{$command} and $command =~ /x$/ and defined($info_state->{'current'}->{'command'}) and "$info_state->{'current'}->{'command'}x" eq $command);
- return $line;
- }
- sub info_default_begin_style_texi($$$$$)
- {
- my $command = shift;
- my $state = shift;
- my $stack = shift;
- my $real_style_command = shift;
- my $remove_texi = shift;
- info_default_open_command($state,$command)
- unless ($info_default_accent_commands{$command} or exists $things_map{$command}
- or $command =~ /^special_(\w+)_(\d+)$/);
- # if ($real_style_command);
- }
- sub info_default_begin_paragraph_texi($$$)
- {
- my $command = shift;
- my $paragraph_macros = shift;
- my $paragraph_command = shift;
- #print STDERR "begin_paragraph $command\n";
- my $state = shift;
- my $stack = shift;
- info_default_open_command($state,$command);
- foreach my $style_command (@$paragraph_macros)
- {
- #print STDERR "para stack: $style_command->{'style'}\n";
- info_default_open_command($state,$style_command->{'style'});
- }
- }
- sub info_default_simple_command($$$$$)
- {
- my $command = shift;
- my $in_preformatted = shift;
- my $in_math = shift;
- my $line_nr = shift;
- my $state = shift;
- my $result = $simple_map{$command};
- $result = $simple_map_math{$command} if ($in_math and defined($simple_map_math{$command}));
- # discards '-' '|' '/' and ':'. If ':' is associated with a punctuation
- # character it is added to the tree in info_default_colon_command
- return info_default_store_text($state,$result,$command) if ($result ne '');
- return '';
- }
- sub info_default_colon_command($)
- {
- my $punctuation_character = shift;
- if (defined($colon_command_punctuation_characters{$punctuation_character})
- and $punctuation_character =~ /^[$punctuation_characters]$/)
- {
- return info_default_store_text(undef,$colon_command_punctuation_characters{$punctuation_character}, ':');
- }
- else
- {
- return info_default_store_text(undef,$punctuation_character);
- }
- }
- sub info_default_thing_command($$$$$$)
- {
- my $command = shift;
- my $text = shift;
- my $in_preformatted = shift;
- my $in_math = shift;
- my $line_nr = shift;
- my $state = shift;
- my $result = $things_map{$command};
- #return info_default_close_command($state, $command, $result, $text, '');
- return info_default_store_text($state, $result, $command);
- # return $result . $text;
- }
- sub info_default_style($$$$$$$$$$)
- {
- my $style = shift;
- my $command = shift;
- my $text = shift;
- my $args = shift;
- my $no_close = shift;
- my $no_open = shift;
- my $line_nr = shift;
- my $state = shift;
- my $command_stack = shift;
- my $kept_line_nrs = shift;
- my $begin = '';
- my $end = '';
- # note that the $text is always discarded for closed commands
- # the formatting is done right here, and the result is entered as text below.
- if ($info_default_leaf_command{$command})
- {
- my $style_index = 0;
- my @formatted_args = ();
- foreach my $arg (@$args)
- {
- # we don't use style, since we only set 'orig_args' in style_map
- # and not in style_map_pre.
- my $arg_style = $style_map{$command}->{'orig_args'}->[$style_index];
- my $new_state = main::duplicate_formatting_state($state);
- if ($arg_style eq 'normal')
- {
- push @formatted_args, main::substitute_line($arg, "\@$command", $new_state);
- }
- elsif ($arg_style eq 'code')
- {
- $new_state->{'code_style'} = 1;
- push @formatted_args, main::substitute_line($arg, "\@$command", $new_state);
- }
- else
- {
- print STDERR "Unknown arg style($style_index) $arg_style for $command, $state->{'remove_texi'}\n";
- }
- $style_index++;
- }
- $args = \@formatted_args;
- }
- if (defined($style->{'function'}))
- { # in case of an accent, some text is returned here if there are still
- # more accents on the command_stack, otherwise it is put in the tree.
- # Other commands text results are put in the tree below.
- $text = &{$style->{'function'}}($command, $args, $command_stack, $state, $line_nr, $kept_line_nrs);
- }
- elsif ($info_default_leaf_command{$command})
- { # no formatting function but a leaf command, it is just replaced
- # by the formatted argument, and put in the tree below.
- $text = $args->[0];
- }
- if (defined($style->{'begin'}) and !$no_open)
- {
- $begin = $style->{'begin'};
- }
- if (defined($style->{'end'}) and !$no_close)
- {
- $end = $style->{'end'};
- }
- # normal style commands
- unless($special_style{$command} or $info_default_accent_commands{$command} or ($command eq 'hyphenation') or $info_default_leaf_command{$command})
- {
- return info_default_close_command($state, $command, $begin, $end);
- }
- # this is for *ref, images and footnotes text registering and putting
- # in the tree.
- # anchor is already in the tree, from anchor_label.
- if (($special_style{$command} or $info_default_leaf_command{$command}) and $command ne 'anchor')
- {
- return info_default_store_text ($state, $begin.$text.$end, $command);
- }
- # for accents, hyphenation and anchor
- # (though the result for anchor is always an empty string).
- return $begin.$text.$end;
- }
- sub info_default_header ()
- {
- return $Texi2HTML::THISDOC{'info_header'} if (defined($Texi2HTML::THISDOC{'info_header'}));
- # $Texi2HTML::THISDOC{'program'}
- my $input_basename = $Texi2HTML::THISDOC{'input_file_name'};
- $input_basename =~ s/^.*\///;
- $input_basename = $STDIN_DOCU_NAME if ($input_basename eq '-');
- my $output_basename = $Texi2HTML::THISDOC{'filename'}->{'top'};
- $output_basename =~ s/^.*\///;
- my $result = "This is $output_basename, produced by makeinfo version 4.13 from $input_basename. ";
- my $dummy;
- ($dummy, $dummy, $dummy, $result) = info_default_process_para_text($result, 0, {'spaces' => ''}, undef, get_conf('FILLCOLUMN'));
- $result .= "\n\n";
- $result .= "$Texi2HTML::THISDOC{'copying_comment'}";
- if ($info_default_dir_specification)
- {
- $result .= "$info_default_dir_specification\n";
- }
- $Texi2HTML::THISDOC{'info_header'} = $result;
- return $result;
- }
- sub info_default_print_page_head($)
- {
- my $fh = shift;
- my $header = info_default_header();
- print $fh "".$header;
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- $info_state->{'offset_in_file'} += info_default_byte_count($header);
- $info_state->{'blank_line'} = 1 if ($Texi2HTML::THISDOC{'copying_comment'} eq '');
- }
- sub info_default_parent_format($)
- {
- my $parent_format = shift;
- my $in_format = 0;
- while (1)
- {
- if (defined($parent_format->{'command'}) and $info_default_format{$parent_format->{'command'}})
- {
- $in_format = 1;
- last;
- }
- last if (!defined($parent_format->{'parent'}));
- $parent_format = $parent_format->{'parent'};
- }
- return ($parent_format, $in_format);
- }
- sub info_default_paragraph($$$$$$$$$$$$)
- {
- my $text = shift;
- my $align = shift;
- my $indent = shift;
- my $paragraph_command = shift;
- my $paragraph_command_formatted = shift;
- my $paragraph_number = shift;
- my $format = shift;
- my $item_nr = shift;
- my $enumerate_style = shift;
- my $number = shift;
- my $command_stack_at_end = shift;
- my $command_stack_at_begin = shift;
- my $top_stack = '';
- $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin));
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- my ($parent_format, $in_format);
- ($parent_format, $in_format) = info_default_parent_format($info_state->{'current'}->{'parent'});
- info_default_increment_paragraph ($in_format, $parent_format, $info_state);
- my $additional_args = {'top_stack' => $top_stack, 'parent_format' => $parent_format};
- $additional_args->{'paragraph_in_element_nr'} = ($info_state->{'paragraph_in_element_nr'} - 1) if (!$in_format);
-
- return info_default_close_command(undef, 'paragraph', undef, undef, $additional_args);
- }
- # currently not used, but could be used if info_default_preformatted
- # return something that is not 'false', for example spaces, though we
- # want the preformatted to be ignored. Though it is not sure that if there
- # are spaces we want to ignore the preformatted.
- sub info_default_empty_preformatted($)
- {
- my $text = shift;
- my $result = info_default_preformatted($text, undef, undef, undef, undef,
- undef, undef, undef, undef, undef, undef, undef);
- return 0;
- }
- sub info_default_preformatted($$$$$$$$$$$$)
- {
- my $text = shift;
- my $pre_style = shift;
- my $class = shift;
- my $leading_command = shift;
- my $leading_command_formatted = shift;
- my $preformatted_number = shift;
- my $format = shift;
- my $item_nr = shift;
- my $enumerate_style = shift;
- my $number = shift;
- my $command_stack_at_end = shift;
- my $command_stack_at_begin = shift;
- return info_default_close_command(undef, 'preformatted');
- }
- sub info_default_node_line($$)
- {
- my $element = shift;
- my $info_state = shift;
- my $outfile = $Texi2HTML::THISDOC{'filename'}->{'top'};
- $outfile = $STDOUT_DOCU_NAME if ($outfile eq '-');
- my $result = "\x{1F}\nFile: $outfile, Node: $element->{'text'}";
- if (defined($element->{'NodeNext'}))
- { # This is not translatable
- $result .= ", Next: $element->{'NodeNext'}->{'text'}";
- }
- if (defined($element->{'NodePrev'}))
- {
- $result .= ", Prev: $element->{'NodePrev'}->{'text'}";
- }
- if (defined($element->{'NodeUp'}))
- {
- $result .= ", Up: $element->{'NodeUp'}->{'text'}";
- }
- $result .= "\n\n";
- # the line_count is ahead from the number of lines by one.
- $info_state->{'line_count'} = 3;
- $info_state->{'offset_in_file'} += info_default_byte_count($result);
- $info_state->{'blank_line'} = 1;
- return $result;
- }
- sub info_default_element_heading($$$$$$$$$$$$)
- {
- my $element = shift;
- my $command = shift;
- my $texi_line = shift;
- my $line = shift;
- my $in_preformatted = shift;
- my $one_section = shift;
- my $element_heading = shift;
- my $first_in_page = shift;
- my $is_top = shift;
- my $previous_is_top = shift;
- my $command_line = shift;
- my $element_id = shift;
- my $new_element = shift;
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- # FIXME use $element or $Texi2HTML::THIS_ELEMENT? Main program should
- # ensure they are the same.
- if ($new_element and ($element ne $new_element and $element->{'node'}))
- {
- die "There is a new element, but element `$element->{'texi'}' is not the new element\n";
- }
- # FIXME
- # non node element may appear if the element appears before the first
- # node/section element. For example `element not associated with a node'
- # won't be associated with a node.
- # @unnumbered element not associated with a node
- # @node Top
- # @top Top element
- if (!$element->{'node'})
- {
- return &$heading($element, $command, $texi_line, $line, $in_preformatted, $one_section, $element_heading);
- }
- my $before = '';
- $element->{'info_offset'} = $info_state->{'offset_in_file'};
- push @{$info_state->{'pending_tags'}}, $element;
- my $result = info_default_node_line($element, $info_state);
- $info_default_footnote_index = 0;
- $info_default_current_node = $element;
-
- return $before.$result;
- }
- sub info_default_heading($$$$$;$$)
- {
- my $element = shift;
- my $command = shift;
- my $texi_line = shift;
- my $line = shift;
- my $in_preformatted = shift;
- my $one_section = shift;
- my $element_heading = shift;
- die "Heading called for a node\n" if ($element->{'node'});
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- $info_state->{'paragraph_in_element_nr'} = 0;
- if (!defined($element->{'texi'}))
- {
- main::msg_debug("for $element, element->{'texi'} not defined, texi_line: $texi_line");
- }
- elsif (!defined($element->{'text'}))
- {
- main::msg_debug("for $element, $element->{'texi'}, element->{'text'} not defined");
- }
- return '' if ($element->{'tag'} eq 'part');
- my $text = "$element->{'text'}";
- # when @top is empty, use settitle
- $text = $Texi2HTML::THISDOC{'settitle'} if (!length($text) and $element->{'tag'} eq 'top' and defined ($Texi2HTML::THISDOC{'settitle'}) and length($Texi2HTML::THISDOC{'settitle'}));
- my $result = &$heading_text ("\@$command", $text, $element->{'level'});
- $result .= "\n";
- return info_default_store_text($state, $result, $command, {'heading_command' => 1});
- }
- sub info_default_normal_text($$$$$$$;$)
- {
- my @initial_args = @_;
- my $text = shift;
- my $in_raw_text = shift; # remove_texi
- my $in_preformatted = shift;
- my $in_code = shift;
- my $in_math = shift;
- my $in_simple = shift;
- my $style_stack = shift;
- my $state = shift;
- # This is always done here since it is not done in t2h_utf8_normal_text
- $text = uc($text) if (in_cmd($style_stack, 'var'));
- # ENCODING_NAME should be defined, but maybe
- # not when parsing commands in first or second pass, and removing texi
- # like what is done for @setfilename.
- if (get_conf('ENABLE_ENCODING') and defined(get_conf('ENCODING_NAME')) and (get_conf('ENCODING_NAME') eq 'utf-8') and get_conf('USE_UNICODE'))
- {
- $text = &t2h_utf8_normal_text(@initial_args);
- }
- else
- {
- #print STDERR "info_default_normal_text $text $in_preformatted $in_code \n";
- $text = uc($text) if (in_cmd($style_stack, 'sc'));
- if (! $in_code and !$in_preformatted)
- {
- $text =~ s/---/\x{1F}/g;
- $text =~ s/--/-/g;
- $text =~ s/\x{1F}/--/g;
- $text =~ s/``/"/g;
- $text =~ s/\'\'/"/g;
- }
- }
- # accented characters are not handled as normal text, but when the last
- # accent command on the stack is closed.
- if ($style_stack and @$style_stack and $info_default_accent_commands{$style_stack->[-1]})
- {
- return $text;
- }
- #print STDERR "NORMAL\n";
- return info_default_store_text($state,$text);
- }
- # this is not called in preformatted
- sub info_default_empty_line($$)
- {
- my $text = shift;
- my $state = shift;
- #ignore the line if it just follows a deff
- #return '' if ($state->{'deff_line'});
- return info_default_store_text($state,$text);
- # return '';
- }
- # change interface?
- sub info_default_anchor_label($$$$)
- {
- my $id = shift;
- my $anchor_text = shift;
- my $anchor_reference = shift;
- my $in_special_region = shift;
- return '' if ($in_special_region);
- #print STDERR "Storing anchor $anchor_reference->{'text'}\n";
- main::line_warn(__("anchor outside of any node, it won't be registered"), $Texi2HTML::THISDOC{'line_nr'}) if (!defined($info_default_current_node));
- return info_default_store_text(undef,undef,'anchor',{'anchor_reference' => $anchor_reference});
- }
- sub info_default_acronym_like($$$$$$)
- {
- my $command = shift;
- my $acronym_texi = shift;
- my $acronym_text = shift;
- my $with_explanation = shift;
- my $explanation_lines = shift;
- my $explanation_text = shift;
- my $explanation_simply_formatted = shift;
- if ($with_explanation)
- {
- return "$acronym_text ($explanation_text)";
- }
- else
- {
- return "$acronym_text";
- }
- }
- sub info_default_print_page_foot($)
- {
- my $fh = shift;
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- my $indirect = 0;
- if (!defined ($info_state->{'pending_tags'}))
- { # i18n
- main::document_warn ("Document without nodes.");
- }
- else
- {
- $indirect = 1 if ($info_default_out_file_nr > 1);
- if ($indirect)
- {
- close ($Texi2HTML::THISDOC{'FH'});
- unless (rename ("$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'filename'}->{'top'}", "$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'filename'}->{'top'}-1"))
- {
- main::document_warn ("Rename $Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'filename'}->{'top'} failed: $!");
- }
-
- my $INDIRECT = main::open_out("$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'filename'}->{'top'}");
- print $INDIRECT "".info_default_header();
- print $INDIRECT "\x{1F}\nIndirect:";
- foreach my $indirect (@info_default_pending_indirect)
- {
- print $INDIRECT "\n$indirect->{'file'}: $indirect->{'offset'}";
- }
- $fh = $INDIRECT;
- }
- # makeinfo seems to add systematically an additional \n, done just below
- print $fh "\n\x{1F}\nTag Table:\n";
-
- if ($indirect)
- {
- print $fh "(Indirect)\n";
- }
- my $Top_seen;
- foreach my $element (@{$info_state->{'pending_tags'}})
- {
- my $prefix;
- $prefix = 'Node' if ($element->{'node'});
- $prefix = 'Ref' if ($element->{'anchor'} or $element->{'float'});
- print $fh "$prefix: $element->{'text'}\x{7F}$element->{'info_offset'}\n";
- $Top_seen = 1 if ($element->{'text'} =~ /^top$/i);
- }
- if (!$Top_seen)
- {# i18n
- main::document_warn ("Document without Top node.");
- }
- print $fh "\x{1F}\nEnd Tag Table\n";
- }
- # IN_ENCODING is the documentencoding transformed to the encoding names
- # usually seen in html. This is what the info readers should understand.
- my $coding = get_conf('IN_ENCODING');
- $coding = get_conf('documentencoding') if (!defined($coding));
- if (defined($coding))
- {
- print $fh "\n\x{1F}\nLocal Variables:\ncoding: $coding\nEnd:\n";
- }
- }
- sub info_default_print_Top_footer($$$)
- {
- my $fh = shift;
- my $end_page = shift;
- my $element = shift;
- if ($end_page)
- {
- &$print_page_foot($fh);
- }
- info_default_end_section($fh, $end_page, $element);
- }
- sub info_default_footnote_texi($$$)
- {
- my $text = shift;
- my $state = shift;
- my $style_stack = shift;
-
- unless ($state->{'outside_document'} or (defined($state->{'multiple_pass'}) and $state->{'multiple_pass'} > 0))
- {
- $info_default_footnote_index++;
- }
- my $footnote_number = $info_default_footnote_index;
- $footnote_number = $NO_NUMBER_FOOTNOTE_SYMBOL if (!get_conf('NUMBER_FOOTNOTES'));
- return "($footnote_number) $text";
- #return undef;
- }
- sub info_default_print_section
- {
- my $fh = shift;
- my $first_in_page = shift;
- my $previous_is_top = shift;
- my $element = shift;
- my $nw = main::print_lines($fh);
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- if (!$info_state->{'blank_line'})
- {
- my $end = "\n";
- $info_state->{'offset_in_file'} += info_default_byte_count($end);
- $info_state->{'line_count'}++;
- print $fh "$end";
- }
- if (@info_default_pending_footnotes)
- {
- my $footnote_text;
- my $footnote_element;
- if (get_conf('footnotestyle') eq 'separate')
- {
- my $node_ref = $info_default_current_node;
- # thee is a warning when processing the footnote, like
- # "Footnote defined without parent node"
- $node_ref = {'text' => 'no node', 'file' => ''} if (!defined($node_ref));
- $footnote_element = { 'NodeUp' => $node_ref,
- 'text' => $node_ref->{'text'} . "-Footnotes",
- 'file' => $node_ref->{'file'},
- 'info_offset' => $info_state->{'offset_in_file'},
- 'node' => 1,
- };
- $footnote_element->{'element_ref'} = $footnote_element;
- push @{$info_state->{'pending_tags'}}, $footnote_element;
- $footnote_text = info_default_node_line($footnote_element, $info_state);
- }
- else
- { # FIXME i18n?
- $footnote_text = " ---------- Footnotes ----------\n\n";
- $info_state->{'offset_in_file'} += info_default_byte_count($footnote_text);
- $info_state->{'line_count'} += 2;
- #print STDERR "MMMMMMMMMMMMMMMMMM $info_state->{'line_count'}\n";
- }
- while (@info_default_pending_footnotes)
- {
- #push @info_default_pending_footnotes, [$lines, $footnote_text, ${info_default_footnote_index}, $node_name, $footnote_info_state];
- my $footnote = shift @info_default_pending_footnotes;
- my $foot_nr = $footnote->{'footnote_index'};
- my $node_name = $footnote->{'node_name'};
- my $lines = $footnote->{'lines'};
- push @{$info_state->{'pending_tags'}}, {'anchor' => 1, 'text' => "${node_name}-Footnote-${foot_nr}", 'info_offset' => $info_state->{'offset_in_file'} };
- my $footnote_info_state = $footnote->{'footnote_info_state'};
- my $footnote_result = shift @{$lines};
- # this is used to keep track of the size when there were
- # leading spaces that will be removed below. This is only used
- # to get the difference, the value itself is not of use.
- my $initial_length = info_default_byte_count($footnote_result);
-
- $footnote_result =~ s/^\s*//;
- #$footnote_result = " ($foot_nr) " . $footnote_result;
- $footnote_result = ' ' x get_conf('paragraphindent') . $footnote_result;
- foreach my $footnote_pending_tags(@{$footnote_info_state->{'pending_tags'}})
- {
- $footnote_pending_tags->{'info_offset'} += $info_state->{'offset_in_file'} + info_default_byte_count($footnote_result) - $initial_length;
- push @{$info_state->{'pending_tags'}}, $footnote_pending_tags;
- }
- foreach my $footnote_pending_index_entry(@{$footnote_info_state->{'pending_index_entries'}})
- {
- #print STDERR "TTTTTTTTTTT($footnote_pending_index_entry->{'index_entry_reference'}->{'entry'}) $footnote_pending_index_entry->{'line_nr'} $info_state->{'line_count'}\n";
- $footnote_pending_index_entry->{'line_nr'} += $info_state->{'line_count'};
- $footnote_pending_index_entry->{'index_entry_reference'}->{'real_element'} = $footnote_element if (get_conf('footnotestyle') eq 'separate');
- }
- my $line;
- while (@$lines)
- {
- $line = shift @$lines;
- $footnote_result .= $line;
- }
- my ($line_passed, $end_of_line, $last_line, $text_indented, $blank_line) = info_default_count_lines($footnote_result);
- if ($line_passed == 0)
- {# certainly out of paragraph commands
- $footnote_result =~ s/\s*$//;
- $footnote_result .= "\n";
- $line_passed = 1;
- }
- unless (($last_line !~ /\S/ and $end_of_line) or ($blank_line))
- {
- $footnote_result .= "\n";
- $line_passed += 1;
- }
-
- $info_state->{'offset_in_file'} += info_default_byte_count($footnote_result);
- $info_state->{'line_count'} += $line_passed;
- $footnote_text .= $footnote_result;
- }
- print $fh "$footnote_text";
- }
- }
- sub info_default_end_section($$$)
- {
- my $fh = shift;
- my $end_foot_navigation = shift;
- my $element = shift;
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- if (defined(get_conf('SPLIT_SIZE')) and
- $info_state->{'offset_in_file'} > ($info_default_out_file_nr) * get_conf('SPLIT_SIZE'))
- {
- if ($info_default_out_file_nr == 1)
- { # push also the first node, which is always the first pending_tags
- push @info_default_pending_indirect, {'file'=>"$Texi2HTML::THISDOC{'filename'}->{'top'}-$info_default_out_file_nr", 'offset' => $info_state->{'pending_tags'}->[0]->{'info_offset'} };
- }
- $info_default_out_file_nr++;
- # these file descriptors leak, but this allows the user to write a
- # foot navigation himself, otherwise he would write on a closed file
- # descriptor
- #close($Texi2HTML::THISDOC{'FH'});
- if (!$end_foot_navigation)
- {
- main::open_out_file("$Texi2HTML::THISDOC{'filename'}->{'top'}-$info_default_out_file_nr");
- #print STDERR "X-$info_default_out_file_nr: $info_state->{'offset_in_file'}\n";
- &$print_page_head($Texi2HTML::THISDOC{'FH'});
- push @info_default_pending_indirect, {'file'=>"$Texi2HTML::THISDOC{'filename'}->{'top'}-$info_default_out_file_nr", 'offset' => $info_state->{'offset_in_file'}};
- }
- }
- }
- sub info_default_one_section($$)
- {
- my $fh = shift;
- my $element = shift;
- &$print_section($fh, 1, 0, $element);
- &$print_page_foot($fh);
- }
- sub info_default_begin_special_region($$$)
- {
- my $region = shift;
- my $state = shift;
- my $lines = shift;
- my $info_state = info_default_get_state ($state);
- # reset paragraph_in_element_nr if out ofdocument formatting
- if ($state->{'outside_document'})
- {
- $info_state->{'paragraph_in_element_nr'} = 0;
- }
- }
- sub info_default_end_special_region($$$)
- {
- my $region = shift;
- my $state = shift;
- my $text = shift;
- my $info_state = info_default_get_state ($state);
- my $end = '';
- if (!$info_state->{'blank_line'})
- {
- $end = "\n";
- $info_state->{'offset_in_file'} += info_default_byte_count($end);
- }
- return $text.$end;
- }
- sub info_default_menu_link($$$$$$$$)
- {
- my $entry = shift;
- my $state = shift;
- my $href = shift;
- my $node = shift;
- my $title = shift;
- my $ending = shift;
- my $has_title = shift;
- my $command_stack = shift;
- my $preformatted = shift;
- $title = '' unless ($has_title);
- $title .= ':' if ($title ne '');
- my $result = "$MENU_SYMBOL$title$node$ending";
- return info_default_store_text($state,$result,'menu_entry');
- }
- # not used, menu is a normal preformatted command
- #sub info_default_menu_command($$$)
- #{
- # my $format = shift;
- # my $text = shift;
- # my $in_preformatted = shift;
- # return info_default_close_command(undef, $format, "* Menu:\n", undef, "\n");
- #}
- sub info_default_complex_format($$)
- {
- my $name = shift;
- my $text = shift;
- my ($begin, $end);
- if ($name eq 'menu')
- {
- main::line_warn(__("\@menu before first node"), $Texi2HTML::THISDOC{'line_nr'}) if (!defined($info_default_current_node));
- $begin = "* Menu:\n\n";
- }
- elsif ($name eq 'direntry')
- {
- main::line_warn(__("\@direntry after first node"), $Texi2HTML::THISDOC{'line_nr'}) if (defined($info_default_current_node));
- $begin = "START-INFO-DIR-ENTRY\n";
- $end = "END-INFO-DIR-ENTRY\n";
- }
- return info_default_close_command(undef, $name, $begin, $end);
- }
- sub info_default_quotation($$$$$)
- {
- my $command = shift;
- my $text = shift;
- my $argument_text = shift;
- my $argument_text_texi = shift;
- my $authors = shift;
- my $attribution;
- if ($authors)
- {
- $attribution = '';
- foreach my $author (@$authors)
- {
- my $author_texi = $author->{'author_texi'};
- chomp($author_texi);
- $attribution .= gdt("\@center --- \@emph{{author}}\n", {'author' => $author_texi}, {'duplicate' => 1, 'allow_paragraph' => 1});
- }
- }
-
- return info_default_close_command(undef, $command, undef, $attribution);
- }
- sub info_default_misc_commands($$$$$)
- {
- my $command = shift;
- my $line = shift;
- my $args = shift;
- my $stack = shift;
- my $state = shift;
- info_default_store_text($state,undef,$command) if ($command eq 'exdent' or $command eq 'noindent' or $command eq 'indent');
- return ($command, $line, undef);
- }
- sub info_default_external_ref($$$$$$$$$)
- {
- my $type = shift;
- my $section = shift;
- my $book = shift;
- my $file = shift;
- my $href = shift;
- my $cross_ref = shift;
- my $args_texi = shift;
- my $formatted_args = shift;
- my $node = shift;
- return info_default_inforef($formatted_args) if ($type eq 'inforef');
- return info_default_normal_reference($type, $formatted_args);
- }
- sub info_default_internal_ref($$$$$$$$)
- {
- my $type = shift;
- my $href = shift;
- my $short_name = shift;
- my $name = shift;
- my $is_section = shift;
- my $args_texi = shift;
- my $formatted_args = shift;
- my $element = shift;
- $formatted_args->[1] = $name if ($element->{'float'} and (!defined($formatted_args->[1]) or $formatted_args->[1] eq ''));
- return info_default_inforef($formatted_args) if ($type eq 'inforef');
- return info_default_normal_reference($type, $formatted_args);
- }
- sub info_default_normal_reference($$)
- {
- my $command = shift;
- my $formatted_args = shift;
- for (my $i = 0; $i < scalar(@$formatted_args); $i++)
- {
- $formatted_args->[$i] = undef if (defined($formatted_args->[$i]) and
- $formatted_args->[$i] =~ /^\s*$/);
- }
- my $node = $formatted_args->[0];
- # an error, should trigger the message: Undefined node `' in @ref.
- # avoid undef value and use an empty string instead.
- $node = '' if (!defined($node));
- my $name = $formatted_args->[1];
- $name = $formatted_args->[2] if (!defined($name));
- my $file = $formatted_args->[3];
- $file = '' if (!defined($file) and defined($formatted_args->[4]));
- $name = $node if (!defined($name) and defined($file));
- my $result = '*note ';
- $result = '*Note ' if ($command eq 'xref');
- if (defined($name))
- {
- $result .= "${name}: ";
- $result .= "($file)" if (defined($file));
- $result .= "$node";
- $result .= '.' if ($command eq 'pxref');
- }
- else
- {
- $result .= "${node}::";
- }
- return $result;
- }
- sub info_default_inforef($)
- {
- my $formatted_args = shift;
- return info_default_normal_reference('ref', [$formatted_args->[0], $formatted_args->[1], undef, $formatted_args->[2], 'dumb manual name']);
- }
- sub info_default_image_files($$$$)
- {
- my $base = shift;
- my $extension = shift;
- my $texi_base = shift;
- my $texi_extension = shift;
- my @files = ();
- return @files if (!defined($base) or ($base eq ''));
- if (defined($extension) and ($extension ne ''))
- {
- push @files, ["${base}$extension", "${texi_base}$extension"];
- push @files, ["$base.$extension", "$texi_base.$extension"];
- }
- foreach my $ext (@IMAGE_EXTENSIONS)
- {
- push @files, ["$base.$ext", "$texi_base.$ext"];
- }
- return @files;
- }
- sub info_default_image($$$$$$$$$$$$$$$$$)
- {
- my $file = shift;
- my $base = shift;
- my $preformatted = shift;
- my $file_name = shift;
- my $alt = shift;
- my $width = shift;
- my $height = shift;
- my $raw_alt = shift;
- my $extension = shift;
- my $working_dir = shift;
- my $file_path = shift;
- my $in_paragraph = shift;
- my $file_locations = shift;
- my $base_simple_format = shift;
- my $extension_simple_format = shift;
- my $file_name_simple_format = shift;
- my $line_nr = shift;
- my $txt_path;
- my $found_file;
- my @extensions = @IMAGE_EXTENSIONS;
- if (defined($extension) and ($extension ne ''))
- {
- unshift @extensions, ".$extension";
- unshift @extensions, "$extension";
- }
- else
- {
- $extension = undef;
- }
- my $file_found_index = undef;
- my $file_index = 0;
- foreach my $file_location (@$file_locations)
- {
- my ($file_located, $path, $file_simple_format) = @$file_location;
- my $extension = shift @extensions;
- if (defined($path))
- {
- if ($extension eq 'txt' and !defined($txt_path))
- {
- $txt_path = $path;
- }
- elsif (!defined($found_file))
- {
- $found_file = [$file_located, $extension, $file_simple_format];
- $file_found_index = $file_index;
- }
- }
- $file_index++;
- }
- my $text;
- if (defined($txt_path))
- {
- if (open(TXT, "<$txt_path"))
- {
- my $in_encoding = get_conf('IN_ENCODING');
- if (defined($in_encoding) and get_conf('USE_UNICODE'))
- {
- binmode(TXT, ":encoding($in_encoding)");
- }
- $text='[' if ($in_paragraph or $preformatted);
- while (my $img_txt = <TXT>)
- {
- $text .= $img_txt;
- }
- # remove last end of line
- chomp ($text);
- $text .= ']' if ($in_paragraph or $preformatted);
- close(TXT);
- }
- else
- {
- main::line_warn (sprintf(__("\@image file `%s' unreadable: %s"), $txt_path, $!), $line_nr);
- }
- }
- elsif (!defined($found_file))
- {
- main::line_warn (sprintf(__("Cannot find \@image file `%s.txt'"), $base), $line_nr);
- }
- if (defined($found_file) and (!defined($extension) or $file_found_index <= 1))
- {
- my $filename = $found_file->[2];
- $filename =~ s/\\/\\\\/g;
- $filename =~ s/\"/\\\"/g;
- my $result = "\x{00}\x{08}[image src=\"$filename\"";
- if (defined($alt))
- {
- $alt =~ s/\\/\\\\/g;
- $alt =~ s/\"/\\\"/g;
- $result .= " alt=\"$alt\"";
- }
- if (defined($text))
- {
- $text =~ s/\\/\\\\/g;
- $text =~ s/\"/\\\"/g;
- $result .= " text=\"$text\"";
- }
- $result .= "\x{00}\x{08}]";
- return $result;
- }
- return $text if (defined($text));
- return '';
- }
- sub info_default_printindex($$)
- {
- my $index_name = shift;
- my $printindex = shift;
- %info_default_index_entries_counts = ();
- return info_default_store_text(undef,t2h_GPL_default_printindex($index_name,$printindex),'printindex');
- }
- sub info_default_print_index($$)
- {
- my $text = shift;
- my $name = shift;
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- my $before = '';
- if (!$info_state->{'blank_line'})
- {
- $before = "\n";
- }
- return $before if (!defined($text));
- my $result = "\x{00}\x{08}[index\x{00}\x{08}]\n* Menu:\n\n" .$text."\n";
- return $before.$result;
- }
- sub info_default_index_letter($$$)
- {
- my $letter = shift;
- my $id = shift;
- my $text = shift;
- return $text;
- }
- sub info_default_index_entry_label($$$$$$$$$)
- {
- my $identifier = shift;
- my $preformatted = shift;
- my $entry = shift;
- my $index_name = shift;
- my $index_command = shift;
- my $texi_entry = shift;
- my $formatted_entry = shift;
- my $in_region_not_in_output = shift;
- my $index_entry_ref = shift;
- #return '' if ($index_entry_ref->{'hidden'});
- #return '' if (!$index_entry_ref->{'seen_in_output'} and defined($index_entry_ref->{'region'}));
- return '' if ($in_region_not_in_output or !defined($index_entry_ref->{'index_name'}));
- main::line_warn(sprintf(__("Entry for index `%s' outside of any node"), $index_entry_ref->{'index_name'}), $Texi2HTML::THISDOC{'line_nr'}) if (!defined($info_default_current_node) and !$Texi2HTML::THISDOC{'state'}->{'outside_document'});
- my $index_entry_stored = {'index_entry_reference' => $index_entry_ref, 'index_command' => $index_command, 'texi_entry' => $texi_entry};
- return info_default_store_text(undef, undef, 'index_label', $index_entry_stored);
- }
- sub info_default_index_entry($$$$$$$$$$)
- {
- my $text_href = shift;
- my $entry = shift;
- my $element_href = shift;
- my $element_text = shift;
- my $entry_file = shift;
- my $current_element_file = shift;
- my $entry_target = shift;
- my $entry_element_target = shift;
- my $in_region_not_in_output = shift;
- my $index_entry_ref = shift;
- #return '' if ($index_entry_ref->{'hidden'});
- #return '' if (!$index_entry_ref->{'seen_in_output'} and defined($index_entry_ref->{'region'}));
- return '' if ($in_region_not_in_output);
- my $state = {};
- $state = { 'code_style' => 1 } if ($index_entry_ref->{'in_code'});
- $entry = main::substitute_line($index_entry_ref->{'texi'}, "index entry in \@printindex", $state);
- return '' if ($entry =~ /^\s*$/);
- my $entry_nr = '';
- if (!defined($info_default_index_entries_counts{$entry}))
- {
- $info_default_index_entries_counts{$entry} = 0;
- }
- else
- {
- $info_default_index_entries_counts{$entry} ++;
- $entry_nr = ' <'.$info_default_index_entries_counts{$entry}.'>';
- }
- my $result = "* $entry${entry_nr}: ";
- if (t2h_default_string_width($result) < $info_default_index_length_to_node)
- {
- $result .= ' ' x($info_default_index_length_to_node - t2h_default_string_width($result));
- }
- #print STDERR "DDDDDDDDDDD $index_entry_ref `$index_entry_ref->{'texi'}'\n";
- my $info_index_entry_ref = $info_default_index_entries{$index_entry_ref};
- my $line_nr = $info_index_entry_ref->{'line_nr'};
- my $real_element_text;
- my $element = $index_entry_ref->{'real_element'};
- # in case $element->{'text'} is not defined, it certainly means that we
- # are n a special elemet, most likely the virtual element appearing
- # before anything else
- if (!defined($element->{'text'}))
- {
- $real_element_text = gdt('(outside of any node)');
- $line_nr = 0;
- }
- else
- {
- $element = $element->{'element_ref'} if ($element->{'element_ref'});
- $real_element_text = $element->{'text'};
- # this happens for index entries appearing after @printindex. In that case
- # it is considered that they are at the beginning of the node.
- $line_nr = 3 if (defined($line_nr) and $line_nr < 3);
- $line_nr = 4 if (!defined($line_nr));
- }
- $result .= $real_element_text . '.';
- my $max_len = $info_default_index_line_string_length{$index_entry_ref->{'index_name'}};
- $max_len = t2h_default_string_width($line_nr) if (!defined($max_len));
- my $line_nr_spaces = sprintf("%${max_len}d", $line_nr);
- my $line_part = "(line ${line_nr_spaces})";
- #print STDERR "GGGGGGGGGG name: $index_entry_ref->{'index_name'} max: ${max_len} line_nr: `$line_nr' line_nr_spaces `$line_nr_spaces' $line_part \n";
- if (t2h_default_string_width($result)+t2h_default_string_width($line_part) +1 > get_conf('FILLCOLUMN'))
- {
- $result .= "\n" . ' ' x (get_conf('FILLCOLUMN') - t2h_default_string_width($line_part)) ;
- }
- else
- {
- $result .= ' ' x (get_conf('FILLCOLUMN') - t2h_default_string_width($line_part) - t2h_default_string_width($result));
- }
- $result .= "$line_part\n";
- return $result;
- }
- sub info_default_index_summary($$)
- {
- my $alpha = shift;
- my $nonalpha = shift;
- return '';
- }
- sub info_default_summary_letter
- {
- return '';
- }
- sub info_default_foot_line_and_ref($$$$$$$$)
- {
- my $foot_num = shift;
- my $relative_num = shift;
- my $footid = shift;
- my $docid = shift;
- my $from_file = shift;
- my $footnote_file = shift;
- my $lines = shift;
- my $state = shift;
-
- my $footnote_state = $Texi2HTML::THISDOC{'state'};
- my $footnote_info_state = info_default_get_state ($footnote_state);
- my $footnote_text = "($info_default_footnote_index)";
- $footnote_text = "($NO_NUMBER_FOOTNOTE_SYMBOL)" if (!get_conf('NUMBER_FOOTNOTES'));
- my $node_name;
- $node_name = '';
- if (defined($info_default_current_node))
- {
- $node_name = $info_default_current_node->{'text'};
- }
- else
- { # i18n
- # no warning when outside of document, for footnotes in
- # titlepage and copying
- main::line_error(__("Footnote defined without parent node"), $Texi2HTML::THISDOC{'line_nr'}) unless ($footnote_state->{'outside_document'});
- #print STDERR "".main::context_string()."\n";
- }
- if (get_conf('footnotestyle') eq 'separate')
- {
- $footnote_text .= ' (' . info_default_normal_reference('pxref', ["${node_name}-Footnote-${info_default_footnote_index}"]) . ')';
- }
- push @info_default_pending_footnotes, {'lines' => $lines,
- 'footnote_text' => $footnote_text,
- 'footnote_index' => ${info_default_footnote_index},
- 'node_name' => $node_name,
- 'footnote_info_state' => $footnote_info_state}
- unless ($state->{'outside_document'} or (defined($state->{'multiple_pass'}) and $state->{'multiple_pass'} > 0));
- return ([], $footnote_text);
- }
- sub info_default_foot_lines($)
- {
- my $lines = shift;
- #my $state = $Texi2HTML::THISDOC{'state'};
- #my $info_state = info_default_get_state ($state);
- @$lines = ();
- }
- # remark: table_item is the html one, but it gets added to the table text
- # on the stack, and is ignored there (in info_default_format).
- sub info_default_format_list_item_texi($$$$)
- {
- my $format = shift;
- my $line = shift;
- my $prepended = shift;
- my $command = shift;
- my $number = shift;
- my $open_command = 0;
- my $result_line;
- $command = 'bullet' if ((!defined($command) or $command eq '') and (!defined($prepended) or $prepended eq '') and $format eq 'itemize');
- $prepended = "\@$command\{\}" if (defined($command) and $command ne '');
- $prepended = "$number." if (defined($number) and $number ne '');
-
- $line =~ s/^\s*//;
-
- if (defined($command) and $command ne '' and $format ne 'itemize')
- {
- #@*table
- $line =~ s/\s*$//;
- if (exists ($style_map{$command}))
- {
- $result_line = "\@$command\{$line\}\n";
- }
- elsif (exists ($things_map{$command}))
- {
- $result_line = "\@$command\{\} $line\n";
- }
- else
- {
- $result_line = "\@$command $line\n";
- }
- }
- # elsif (defined($prepended) and $prepended ne '')
- # { # @enumerate and @itemize
- # $prepended =~ s/^\s*//;
- # $prepended =~ s/\s*$//;
- # $result_line = $prepended . ' ' . $line;
- # }
- return ($result_line, $open_command);
- }
- sub info_default_list_item($$$$$$$$$$$$)
- {
- my $text = shift;
- my $format = shift;
- my $command = shift;
- my $formatted_command = shift;
- my $item_nr = shift;
- my $enumerate_style = shift;
- my $number = shift;
- my $prepended = shift;
- my $prepended_formatted = shift;
- my $only_inter_item_commands = shift;
- my $before_items = shift;
- my $item_command = shift;
- # my $prepend = '';
- # if (defined($formatted_command) and $formatted_command ne '')
- # {
- # $prepend = $formatted_command;
- # }
- # return $prepend . $text;
- # $command = 'bullet' if ((!defined($command) or $command eq '') and (!defined($prepended) or $prepended eq '') and $format eq 'itemize');
- $formatted_command = $things_map{'bullet'} if ((!defined($command) or $command eq '') and (!defined($prepended) or $prepended eq '') and $format eq 'itemize');
- if ($format !~ /table$/)
- {
- my $result = '';
- if ($format eq 'enumerate')
- {
- $result = $number.'.';
- }
- elsif ($format eq 'itemize')
- {
- if (defined($formatted_command) and $formatted_command ne '')
- {
- $result = $formatted_command;
- }
- elsif (defined ($prepended_formatted) and $prepended_formatted ne '')
- {
- $prepended_formatted =~ s/^\s*//;
- $prepended_formatted =~ s/\s*$//;
- $result = $prepended_formatted;
- }
- }
- else
- {
- $result = '';
- }
- $result .= ' ' if ($result ne '');
- return info_default_close_command (undef, $item_command, $result);
- }
- return $text;
- }
- sub info_default_format($$$)
- {
- my $tag = shift;
- my $element = shift;
- my $text = shift;
- # currently no command has something else than '' as $element.
- # notice that any text is discarded
- $element = undef if ($element eq '');
- my $element_end = $element;
- if (defined($element) and $element =~ /^(\w+)(\s+)(.+)/)
- {
- $element = $1;
- $element_end = $2;
- }
- return info_default_close_command(undef, $tag, $element, $element_end);
- }
- sub info_default_tab_item_texi($$$$$$)
- {
- my $command = shift;
- my $commands_stack = shift;
- my $stack = shift;
- my $state = shift;
- my $line = shift;
- my $line_nr = shift;
- $line =~ s/^\s*//;
- my $format;
- my $info_state = info_default_get_state ($state);
- #$format = $commands_stack->[-1] if (defined($commands_stack) and @$commands_stack and $commands_stack->[-1]);
- my ($parent_format, $in_format) = info_default_parent_format($info_state->{'current'});
- print STDERR "Not in_format in info_default_tab_item_texi\n" if (!$in_format);
- $format = $parent_format->{'command'};
- # in case of an @item or @tab outside of any format $format will be
- # undefined, or not multitable for a @tab.
- # however the main program still do as if something was opened, plus
- # it is checked there that the nesting is correct
- #return $line if (!defined($format) or $command eq 'tab' and $format ne 'multitable');
- #print STDERR "tab_item_texi $format $command $commands_stack, $stack, $state, $line, ".main::format_line_number($line_nr)."\n";
- if ($format eq 'multitable')
- { # even if it is a tab, if it is not already in a multitable_row, one
- # should be started
- if ($command ne 'tab' or $info_state->{'current'}->{'command'} ne 'multitable_row')
- {
- info_default_open_command($state, 'multitable_row');
- }
- info_default_open_command($state, 'multitable_cell');
- }
- elsif ($format =~ /table$/)
- {
- info_default_store_text ($state, undef, $command, {'format_name' => $format});
- }
- else
- {
- info_default_open_command ($state, $command, {'format_name' => $format});
- }
- # this allows removing blank space in front of the item or tab argument
- return $line;
- }
- sub info_default_sp($$)
- {
- my $number = shift;
- my $preformatted = shift;
- my $result = "\n" x $number;
- return info_default_store_text(undef,$result,'sp');
- }
- sub info_default_paragraph_style_command($$)
- {
- my $format = shift;
- my $text = shift;
- return info_default_close_command(undef, $format);
- }
- sub info_default_row($$$$$$$$)
- {
- my $text = shift;
- my $macro = shift;
- my $columnfractions = shift;
- my $prototype_row = shift;
- my $prototype_lengths = shift;
- my $column_number = shift;
- my $only_inter_item_commands = shift;
- my $before_items = shift;
- #print STDERR "info_default_row: $text\n";
- return info_default_close_command(undef, 'multitable_row', undef, undef, {'item_command' => $macro});
- }
- sub info_default_cell($$$$$$$$)
- {
- my $text = shift;
- my $row_macro = shift;
- my $columnfractions = shift;
- my $prototype_row = shift;
- my $prototype_lengths = shift;
- my $column_number = shift;
- my $only_inter_item_commands = shift;
- my $before_items = shift;
- # in general, when before_items, there will be no call to the function
- # since there should never be a text sent back, so that this
- # function will not be called for the first row (the multitable title).
- # However, if there is a @tab before the first @item, the main program
- # is less careful and closes the cell in any case, so before_items
- # has to be checked for that case.
- return info_default_close_command(undef, 'multitable_cell') unless ($before_items);
- }
- sub info_default_table_list($$$$$$$$$)
- {
- my $format_command = shift;
- my $text = shift;
- my $command = shift;
- my $formatted_command = shift;
- # enumerate
- my $item_nr = shift;
- my $enumerate_style = shift;
- # itemize
- my $prepended = shift;
- my $prepended_formatted = shift;
- # multitable
- my $columnfractions = shift;
- my $prototype_row = shift;
- my $prototype_lengths = shift;
- my $column_number = shift;
- die "BUG: $format_command item_nr undef\n" if (!defined($item_nr));
- return info_default_close_command(undef, $format_command, undef, undef, {'total_item_nr' => $item_nr}) if ($format_command ne 'multitable');
- my $columnsize = [];
- if (defined($prototype_lengths) and @$prototype_lengths)
- {
- $columnsize = [ @$prototype_lengths ];
- }
- elsif (defined($columnfractions) and @$columnfractions)
- {
- foreach my $fraction (@$columnfractions)
- {
- push @$columnsize, int($fraction * get_conf('FILLCOLUMN') +0.5);
- }
- }
- else
- { # empty multitable
- #print STDERR "Empty multitable?\n";
- }
- return info_default_close_command(undef, $format_command, undef, undef, {'columns_size' => $columnsize, 'total_item_nr' => $item_nr});
- }
- sub info_default_def_item($$$)
- {
- my $text = shift;
- my $only_inter_item_commands = shift;
- my $command = shift;
- my $format = 'deff_item';
- $format = 'deff_itemx' if ($command =~ /x$/);
- return info_default_close_command(undef, $format);
- }
- sub info_default_def_line($$$$$$$$$$$$$$$$)
- {
- my $category_prepared = shift;
- my $name = shift;
- my $type = shift;
- my $arguments = shift;
- my $index_label = shift;
- my $arguments_array = shift;
- my $arguments_type_array = shift;
- my $unformatted_arguments_array = shift;
- my $command = shift;
- my $class_name = shift;
- my $category = shift;
- my $class = shift;
- my $style = shift;
- my $original_command = shift;
- $name = '' if (!defined($name) or ($name =~ /^\s*$/));
- $type = '' if (!defined($type) or $type =~ /^\s*$/);
- $arguments = '' if (!defined($arguments) or $arguments =~ /^\s*$/);
- my $type_name = '';
- $type_name .= "$type " if ($type ne '');
- $type_name .= $name if ($name ne '');
- my $result = " -- $category_prepared: ${type_name}$arguments";
- $result =~ s/\s*$//;
- $result .= "\n";
- my $state = $Texi2HTML::THISDOC{'state'};
- info_default_store_text(undef,$result,"${command}_line",{'definition_line' => 1});
- my $format = 'deff_item';
- $format = 'deff_itemx' if ($original_command =~ /x$/);
- return info_default_open_command($state, $format);
- }
- sub info_default_def($$)
- {
- my $text = shift;
- my $command = shift;
- return info_default_close_command(undef, $command);
- }
- sub info_default_float($$$$$)
- {
- my $text = shift;
- my $float = shift;
- my $caption = shift;
- my $shortcaption = shift;
- my $additional_arguments;
- if (exists($float->{'id'}))
- {
- $additional_arguments->{'anchor_reference'} = $float;
- main::line_warn(__("float reference outside of any node, it won't be registered"), $Texi2HTML::THISDOC{'line_nr'}) if (!defined($info_default_current_node) and !$Texi2HTML::THISDOC{'state'}->{'outside_document'});
- }
- my $caption_text = '';
- if (defined($float->{'caption_texi'}))
- {
- $caption_text = $caption;
- }
- elsif (defined($float->{'shortcaption_texi'}))
- {
- $caption_text = $shortcaption;
- }
- elsif (defined($caption))
- {
- $caption_text = $caption;
- }
- #return $caption_text;
- return info_default_close_command(undef, 'float', undef, $caption_text, $additional_arguments);
- }
- sub info_default_listoffloats_entry($$$$)
- {
- my $style_texi = shift;
- my $float = shift;
- my $float_style = shift;
- my $caption = shift;
- my $href = shift;
- my @lines = split /^/, $caption;
- $caption = $lines[0];
- $caption = '' if (!defined($caption));
- chomp ($caption);
- my $result = '';
- #$caption .= ':' if ($caption ne '');
- my $caption_entry = "* $float_style: $float->{'text'}.";
- if (t2h_default_string_width($caption_entry) > $info_default_listoffloat_caption_entry_length)
- {
- $caption_entry .= "\n" . ' ' x $info_default_listoffloat_caption_entry_length;
- }
- else
- {
- $caption_entry .= ' ' x ($info_default_listoffloat_caption_entry_length - length($caption_entry));
- }
- my $width = $info_default_listoffloat_caption_entry_length;
- while ($caption =~ s/^(\S+\s*)//)
- {
- my $new_word = $1;
- if ((t2h_default_string_width($new_word) + $width) > get_conf('FILLCOLUMN') - 3)
- {
- $caption_entry .= $info_default_listoffloat_append;
- last;
- }
- else
- {
- $caption_entry .= $new_word;
- $width += t2h_default_string_width($new_word);
- }
- }
- return $caption_entry. "\n";
- }
- sub info_default_listoffloats($$$)
- {
- my $style_texi = shift;
- my $style = shift;
- my $float_entries = shift;
- my $state = $Texi2HTML::THISDOC{'state'};
- my $info_state = info_default_get_state ($state);
- my $result = "* Menu:\n\n";
- foreach my $float_entry (@$float_entries)
- {
- $result .= $float_entry;
- }
- my ($parent_format, $in_format);
- ($parent_format, $in_format) = info_default_parent_format($info_state->{'current'});
- #print STDERR "\@listoffloats not at top level\n" if ($in_format);
- info_default_increment_paragraph ($in_format, $parent_format, $info_state, 'listoffloats');
- return info_default_store_text($state,$result,'listoffloats');
- }
- sub info_default_raw($$)
- {
- my $style = shift;
- my $text = shift;
- my $expanded = 1 if (grep {$style eq $_} @EXPAND);
- # no warning for unknown raw formats
- if ($style eq 'verbatim' or $style eq 'verbatiminclude' or $expanded)
- {
- return info_default_store_text(undef, $text, $style, {'raw_command' => 1});
- }
- return '';
- }
- sub info_default_line_command($$$$)
- {
- my $command = shift;
- my $arg_text = shift;
- my $arg_texi = shift;
- my $state = shift;
- main::line_warn(__("\@dircategory after first node"), $Texi2HTML::THISDOC{'line_nr'}) if (defined($info_default_current_node));
- return '' if ($arg_text eq '');
- $info_default_dir_specification .= "INFO-DIR-SECTION $arg_text\n";
- return '';
- }
- sub info_default_unknown_style($$$$$)
- {
- my $command = shift;
- my $text = shift;
- my $state = shift;
- my $no_close = shift;
- my $no_open = shift;
-
- my ($result, $result_text, $message);
- $result_text = info_default_close_command(undef, $command, undef, undef, undef);
- $message = "Unknown command with braces `\@$command'" if (!$no_open);
- return (1, $result_text, $message);
- }
- 1;
|