12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456 |
- /* insertion.c -- insertions for Texinfo.
- $Id: insertion.c,v 1.72 2009-01-01 07:24:57 olegkat Exp $
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008 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/>. */
- #include "system.h"
- #include "cmds.h"
- #include "defun.h"
- #include "float.h"
- #include "html.h"
- #include "insertion.h"
- #include "macro.h"
- #include "makeinfo.h"
- #include "multi.h"
- #include "xml.h"
- /* Must match list in insertion.h. */
- static char *insertion_type_names[] =
- {
- "cartouche", "copying", "defcv", "deffn", "defivar", "defmac",
- "defmethod", "defop", "defopt", "defspec", "deftp", "deftypecv",
- "deftypefn", "deftypefun", "deftypeivar", "deftypemethod",
- "deftypeop", "deftypevar", "deftypevr", "defun", "defvar", "defvr",
- "detailmenu", "direntry", "display", "documentdescription",
- "enumerate", "example", "float", "flushleft", "flushright", "format",
- "ftable", "group", "ifclear", "ifdocbook", "ifhtml", "ifinfo",
- "ifnotdocbook", "ifnothtml", "ifnotinfo", "ifnotplaintext", "ifnottex",
- "ifnotxml", "ifplaintext", "ifset", "iftex", "ifxml", "itemize", "lisp",
- "menu", "multitable", "quotation", "raggedcenter", "raggedleft",
- "raggedright", "rawdocbook", "rawhtml", "rawtex",
- "rawxml", "smalldisplay", "smallexample", "smallformat", "smalllisp",
- "verbatim", "table", "tex", "vtable", "titlepage", "bad_type"
- };
- /* All nested environments. */
- INSERTION_ELT *insertion_stack = NULL;
- /* How deeply we're nested. */
- int insertion_level = 0;
- /* Set to 1 if we've processed (commentary) text in a @menu that
- wasn't part of a menu item. */
- int had_menu_commentary;
- /* How to examine menu lines. */
- int in_detailmenu = 0;
- /* Whether to examine menu lines. */
- int in_menu = 0;
- /* Set to 1 if <p> is written in normal context.
- Used for menu and itemize. */
- int in_paragraph = 0;
- /* Since an insertion is already in the stack before we reach the switch
- statement, we cannot use is_in_insertion_of_type (always returns true.) Also
- making it return the level found, and comparing it with the current level is
- no use, due to the order of stack. */
- static int float_active = 0;
- /* Unsetting escape_html blindly causes text inside @html/etc. to be escaped if
- used within a rmacro. */
- static int raw_output_block = 0;
- /* Non-zero if a <dl> element has a <dt> element in it. We use this when
- deciding whether to insert a <br> or not. */
- static int html_deflist_has_term = 0;
- const char default_item_function[] = { "@bullet" };
- void
- init_insertion_stack (void)
- {
- insertion_stack = NULL;
- }
- /* Return the type of the current insertion. */
- static enum insertion_type
- current_insertion_type (void)
- {
- return insertion_level ? insertion_stack->insertion : bad_type;
- }
- /* Return the string which is the function to wrap around items, or NULL
- if we're not in an environment where @item is ok. */
- static char *
- current_item_function (void)
- {
- int done = 0;
- INSERTION_ELT *elt = insertion_stack;
- /* Skip down through the stack until we find an insertion with an
- itemize function defined, i.e., skip conditionals, @cartouche, etc. */
- while (!done && elt)
- {
- switch (elt->insertion)
- {
- /* This list should match the one in cm_item. */
- case ifclear:
- case ifhtml:
- case ifinfo:
- case ifnothtml:
- case ifnotinfo:
- case ifnotplaintext:
- case ifnottex:
- case ifnotxml:
- case ifplaintext:
- case ifset:
- case iftex:
- case ifxml:
- case rawdocbook:
- case rawhtml:
- case rawxml:
- case rawtex:
- case tex:
- case cartouche:
- elt = elt->next;
- break;
-
- default:
- done = 1;
- }
- }
- /* item_function usually gets assigned the empty string. */
- return done && (*elt->item_function) ? elt->item_function : NULL;
- }
- /* Parse the item marker function off the input. If result is just "@",
- change it to "@ ", since "@" by itself is not a command. This makes
- "@ ", "@\t", and "@\n" all the same, but their default meanings are
- the same anyway, and let's not worry about supporting redefining them. */
- char *
- get_item_function (void)
- {
- char *item_function;
- char *item_loc;
-
- get_rest_of_line (0, &item_function);
- /* If the document erroneously says
- @itemize @bullet @item foobar
- it's nicer to give an error up front than repeat `@bullet expected
- braces' until we get a segmentation fault. */
- item_loc = strstr (item_function, "@item");
- if (item_loc)
- {
- line_error (_("@item not allowed in argument to @itemize"));
- *item_loc = 0;
- }
- /* If we hit the end of text in get_rest_of_line, backing up
- input pointer will cause the last character of the last line
- be pushed back onto the input, which is wrong. */
- if (input_text_offset < input_text_length)
- backup_input_pointer ();
- if (STREQ (item_function, "@"))
- {
- free (item_function);
- item_function = xstrdup ("@ ");
- }
- return item_function;
- }
- /* Push the state of the current insertion on the stack. */
- static void
- push_insertion (enum insertion_type type, char *item_function)
- {
- INSERTION_ELT *new = xmalloc (sizeof (INSERTION_ELT));
- new->item_function = item_function;
- new->filling_enabled = filling_enabled;
- new->indented_fill = indented_fill;
- new->insertion = type;
- new->line_number = line_number;
- new->filename = xstrdup (input_filename);
- new->inhibited = inhibit_paragraph_indentation;
- new->in_fixed_width_font = in_fixed_width_font;
- new->next = insertion_stack;
- insertion_stack = new;
- insertion_level++;
- }
- /* Pop the value on top of the insertion stack into the
- global variables. */
- void
- pop_insertion (void)
- {
- INSERTION_ELT *temp = insertion_stack;
- if (temp == NULL)
- return;
- in_fixed_width_font = temp->in_fixed_width_font;
- inhibit_paragraph_indentation = temp->inhibited;
- filling_enabled = temp->filling_enabled;
- indented_fill = temp->indented_fill;
- if (temp->item_function == default_item_function)
- temp->item_function = NULL;
- else
- free_and_clear (&(temp->item_function));
- free_and_clear (&(temp->filename));
- insertion_stack = insertion_stack->next;
- free (temp);
- insertion_level--;
- }
- /* Return a pointer to the print name of this
- enumerated type. */
- static const char *
- insertion_type_pname (enum insertion_type type)
- {
- if ((int) type < (int) bad_type)
- {
- if (type == rawdocbook)
- return "docbook";
- else if (type == rawhtml)
- return "html";
- else if (type == rawxml)
- return "xml";
- else if (type == rawtex)
- return "tex";
- else
- return insertion_type_names[(int) type];
- }
- else
- return _("Broken-Type in insertion_type_pname");
- }
- /* Return the insertion_type associated with NAME.
- If the type is not one of the known ones, return BAD_TYPE. */
- enum insertion_type
- find_type_from_name (char *name)
- {
- int index = 0;
- while (index < (int) bad_type)
- {
- if (STREQ (name, insertion_type_names[index]))
- return (enum insertion_type) index;
- if (index == rawdocbook && STREQ (name, "docbook"))
- return rawdocbook;
- if (index == rawhtml && STREQ (name, "html"))
- return rawhtml;
- if (index == rawxml && STREQ (name, "xml"))
- return rawxml;
- if (index == rawtex && STREQ (name, "tex"))
- return rawtex;
- index++;
- }
- return bad_type;
- }
- /* Simple function to query insertion_stack to see if we are inside a given
- insertion type. */
- int
- is_in_insertion_of_type (int type)
- {
- INSERTION_ELT *temp = insertion_stack;
- if (!insertion_level)
- return 0;
- while (temp)
- {
- if (temp->insertion == type)
- return 1;
- temp = temp->next;
- }
- return 0;
- }
- static int
- defun_insertion (enum insertion_type type)
- {
- return 0
- || (type == defcv)
- || (type == deffn)
- || (type == defivar)
- || (type == defmac)
- || (type == defmethod)
- || (type == defop)
- || (type == defopt)
- || (type == defspec)
- || (type == deftp)
- || (type == deftypecv)
- || (type == deftypefn)
- || (type == deftypefun)
- || (type == deftypeivar)
- || (type == deftypemethod)
- || (type == deftypeop)
- || (type == deftypevar)
- || (type == deftypevr)
- || (type == defun)
- || (type == defvar)
- || (type == defvr)
- ;
- }
- /* MAX_NS is the maximum nesting level for enumerations. I picked 100
- which seemed reasonable. This doesn't control the number of items,
- just the number of nested lists. */
- #define max_stack_depth 100
- #define ENUM_DIGITS 1
- #define ENUM_ALPHA 2
- typedef struct {
- int enumtype;
- int enumval;
- } DIGIT_ALPHA;
- DIGIT_ALPHA enumstack[max_stack_depth];
- int enumstack_offset = 0;
- int current_enumval = 1;
- int current_enumtype = ENUM_DIGITS;
- char *enumeration_arg = NULL;
- static void
- start_enumerating (int at, int type)
- {
- if ((enumstack_offset + 1) == max_stack_depth)
- {
- line_error (_("Enumeration stack overflow"));
- return;
- }
- enumstack[enumstack_offset].enumtype = current_enumtype;
- enumstack[enumstack_offset].enumval = current_enumval;
- enumstack_offset++;
- current_enumval = at;
- current_enumtype = type;
- }
- static void
- stop_enumerating (void)
- {
- --enumstack_offset;
- if (enumstack_offset < 0)
- enumstack_offset = 0;
- current_enumval = enumstack[enumstack_offset].enumval;
- current_enumtype = enumstack[enumstack_offset].enumtype;
- }
- /* Place a letter or digits into the output stream. */
- static void
- enumerate_item (void)
- {
- char temp[10];
- if (current_enumtype == ENUM_ALPHA)
- {
- if (current_enumval == ('z' + 1) || current_enumval == ('Z' + 1))
- {
- current_enumval = ((current_enumval - 1) == 'z' ? 'a' : 'A');
- warning (_("lettering overflow, restarting at %c"), current_enumval);
- }
- sprintf (temp, "%c. ", current_enumval);
- }
- else
- sprintf (temp, "%d. ", current_enumval);
- indent (current_output_column () + (current_indent - strlen (temp)));
- add_word (temp);
- current_enumval++;
- }
- static void
- enum_html (void)
- {
- char type;
- int start;
- if (isdigit (*enumeration_arg))
- {
- type = '1';
- start = atoi (enumeration_arg);
- }
- else if (isupper (*enumeration_arg))
- {
- type = 'A';
- start = *enumeration_arg - 'A' + 1;
- }
- else
- {
- type = 'a';
- start = *enumeration_arg - 'a' + 1;
- }
- add_html_block_elt_args ("<ol type=%c start=%d>\n", type, start);
- }
- /* Conditionally parse based on the current command name. */
- void
- command_name_condition (void)
- {
- char *discarder = xmalloc (8 + strlen (command));
- sprintf (discarder, "\n%cend %s", COMMAND_PREFIX, command);
- discard_until (discarder);
- discard_until ("\n");
- free (discarder);
- }
- /* This is where the work for all the "insertion" style
- commands is done. A huge switch statement handles the
- various setups, and generic code is on both sides. */
- void
- begin_insertion (enum insertion_type type)
- {
- int no_discard = 0;
- if (defun_insertion (type))
- {
- push_insertion (type, xstrdup (""));
- no_discard++;
- }
- else
- {
- push_insertion (type, get_item_function ());
- }
- switch (type)
- {
- case menu:
- if (!no_headers)
- close_paragraph ();
- filling_enabled = no_indent = 0;
- inhibit_paragraph_indentation = 1;
- if (html)
- {
- had_menu_commentary = 1;
- }
- else if (!no_headers && !xml)
- add_word ("* Menu:\n");
- if (xml)
- xml_insert_element (MENU, START);
- else
- in_fixed_width_font++;
- next_menu_item_number = 1;
- in_menu++;
- no_discard++;
- break;
- case detailmenu:
- if (!in_menu)
- {
- if (!no_headers)
- close_paragraph ();
- filling_enabled = no_indent = 0;
- inhibit_paragraph_indentation = 1;
- no_discard++;
- }
- if (xml)
- {
- xml_insert_element (DETAILMENU, START);
- skip_whitespace_and_newlines ();
- }
- else
- in_fixed_width_font++;
- in_detailmenu++;
- break;
- case direntry:
- close_single_paragraph ();
- filling_enabled = no_indent = 0;
- inhibit_paragraph_indentation = 1;
- add_word ("START-INFO-DIR-ENTRY\n");
-
- /* The zsh manual, maybe others, wrongly indents the * line of the
- direntry in the source. Ignore that whitespace. */
- skip_whitespace_and_newlines ();
- no_discard++;
- break;
- case documentdescription:
- {
- char *desc;
- int start_of_end;
- int save_fixed_width;
- discard_until ("\n"); /* ignore the @documentdescription line */
- start_of_end = get_until ("\n@end documentdescription", &desc);
- save_fixed_width = in_fixed_width_font;
- in_fixed_width_font = 0;
- document_description = expansion (desc, 0);
- free (desc);
- in_fixed_width_font = save_fixed_width;
- input_text_offset = start_of_end; /* go back to the @end to match */
- }
- break;
- case copying:
- /* Save the copying text away for @insertcopying,
- typically used on the back of the @titlepage (for TeX) and
- the Top node (for info/html). */
- if (input_text[input_text_offset] != '\n')
- discard_until ("\n"); /* ignore remainder of @copying line */
- input_text_offset = get_until ("\n@end copying", ©ing_text);
- canon_white (copying_text);
- /* For info, output the copying text right away, so it will end up
- in the header of the Info file, before the first node, and thus
- get copied automatically to all the split files. For xml, also
- output it right away since xml output is never split.
- For html, we output it specifically in html_output_head.
- For plain text, there's no way to hide it, so the author must
- use @insertcopying in the desired location. */
- if (docbook)
- {
- if (!xml_in_bookinfo)
- {
- xml_insert_element (BOOKINFO, START);
- xml_in_bookinfo = 1;
- }
- xml_insert_element (LEGALNOTICE, START);
- }
- if (!html && !no_headers)
- cm_insert_copying ();
- if (docbook)
- xml_insert_element (LEGALNOTICE, END);
- break;
- case quotation:
- /* @quotation does filling (@display doesn't). */
- if (html)
- add_html_block_elt ("<blockquote>\n");
- else
- {
- /* with close_single_paragraph, we get no blank line above
- within @copying. */
- close_paragraph ();
- last_char_was_newline = no_indent = 0;
- indented_fill = filling_enabled = 1;
- inhibit_paragraph_indentation = 1;
- current_indent += default_indentation_increment;
- }
- if (xml)
- xml_insert_quotation (insertion_stack->item_function, START);
- else if (strlen(insertion_stack->item_function))
- execute_string ("@b{%s:} ", insertion_stack->item_function);
- break;
- case example:
- case smallexample:
- case lisp:
- case smalllisp:
- in_fixed_width_font++;
- /* fall through */
- /* Like @example but no fixed width font. */
- case display:
- case smalldisplay:
- /* Like @display but without indentation. */
- case smallformat:
- case format:
- close_single_paragraph ();
- inhibit_paragraph_indentation = 1;
- filling_enabled = 0;
- last_char_was_newline = 0;
- if (html)
- /* Kludge alert: if <pre> is followed by a newline, IE3,
- mozilla, maybe others render an extra blank line before the
- pre-formatted block. So don't output a newline. */
- add_html_block_elt_args ("<pre class=\"%s\">", command);
- if (type != format && type != smallformat)
- {
- current_indent += example_indentation_increment;
- if (html)
- {
- /* Since we didn't put \n after <pre>, we need to insert
- the indentation by hand. */
- int i;
- for (i = current_indent; i > 0; i--)
- add_char (' ');
- }
- }
- break;
- case multitable:
- do_multitable ();
- break;
- case table:
- case ftable:
- case vtable:
- case itemize:
- close_single_paragraph ();
- current_indent += default_indentation_increment;
- filling_enabled = indented_fill = 1;
- #if defined (INDENT_PARAGRAPHS_IN_TABLE)
- inhibit_paragraph_indentation = 0;
- #else
- inhibit_paragraph_indentation = 1;
- #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
- /* Make things work for losers who forget the itemize syntax. */
- if (type == itemize)
- {
- if (!(*insertion_stack->item_function))
- {
- free (insertion_stack->item_function);
- insertion_stack->item_function = (char *) default_item_function;
- }
- }
- if (!*insertion_stack->item_function)
- {
- line_error (_("%s requires an argument: the formatter for %citem"),
- insertion_type_pname (type), COMMAND_PREFIX);
- }
- if (html)
- {
- if (type == itemize)
- {
- add_html_block_elt ("<ul>\n");
- in_paragraph = 0;
- }
- else
- { /* We are just starting, so this <dl>
- has no <dt> children yet. */
- html_deflist_has_term = 0;
- add_html_block_elt ("<dl>\n");
- }
- }
- if (xml)
- xml_begin_table (type, insertion_stack->item_function);
- while (input_text[input_text_offset] == '\n'
- && input_text[input_text_offset+1] == '\n')
- {
- line_number++;
- input_text_offset++;
- }
- break;
- case enumerate:
- close_single_paragraph ();
- no_indent = 0;
- #if defined (INDENT_PARAGRAPHS_IN_TABLE)
- inhibit_paragraph_indentation = 0;
- #else
- inhibit_paragraph_indentation = 1;
- #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
- current_indent += default_indentation_increment;
- filling_enabled = indented_fill = 1;
- if (html)
- {
- enum_html ();
- in_paragraph = 0;
- }
- if (xml)
- xml_begin_enumerate (enumeration_arg);
-
- if (isdigit (*enumeration_arg))
- start_enumerating (atoi (enumeration_arg), ENUM_DIGITS);
- else
- start_enumerating (*enumeration_arg, ENUM_ALPHA);
- break;
- /* @group produces no output in info. */
- case group:
- /* Only close the paragraph if we are not inside of an
- @example-like environment. */
- if (xml)
- xml_insert_element (GROUP, START);
- else if (!insertion_stack->next
- || (insertion_stack->next->insertion != display
- && insertion_stack->next->insertion != smalldisplay
- && insertion_stack->next->insertion != example
- && insertion_stack->next->insertion != smallexample
- && insertion_stack->next->insertion != lisp
- && insertion_stack->next->insertion != smalllisp
- && insertion_stack->next->insertion != format
- && insertion_stack->next->insertion != smallformat
- && insertion_stack->next->insertion != flushleft
- && insertion_stack->next->insertion != flushright))
- close_single_paragraph ();
- break;
- case cartouche:
- if (html)
- add_html_block_elt ("<p><table class=\"cartouche\" summary=\"cartouche\" border=\"1\"><tr><td>\n");
- if (in_menu)
- no_discard++;
- break;
- case floatenv:
- /* Cannot nest floats, so complain. */
- if (float_active)
- {
- line_error (_("%cfloat environments cannot be nested"), COMMAND_PREFIX);
- pop_insertion ();
- break;
- }
- float_active++;
- { /* Collect data about this float. */
- /* Example: @float [FLOATTYPE][,XREFLABEL][,POSITION] */
- char floattype[200] = "";
- char xreflabel[200] = "";
- char position[200] = "";
- char *text;
- char *caption;
- char *shortcaption;
- int start_of_end;
- int save_line_number = line_number;
- int save_input_text_offset = input_text_offset;
- int i;
- if (strlen (insertion_stack->item_function) > 0)
- {
- int i = 0, t = 0, c = 0;
- while (insertion_stack->item_function[i])
- {
- if (insertion_stack->item_function[i] == ',')
- {
- switch (t)
- {
- case 0:
- floattype[c] = '\0';
- break;
- case 1:
- xreflabel[c] = '\0';
- break;
- case 2:
- position[c] = '\0';
- break;
- }
- c = 0;
- t++;
- i++;
- continue;
- }
- switch (t)
- {
- case 0:
- floattype[c] = insertion_stack->item_function[i];
- break;
- case 1:
- xreflabel[c] = insertion_stack->item_function[i];
- break;
- case 2:
- position[c] = insertion_stack->item_function[i];
- break;
- }
- c++;
- i++;
- }
- }
- skip_whitespace_and_newlines ();
- start_of_end = get_until ("\n@end float", &text);
- /* Get also the @caption. */
- i = search_forward_until_pos ("\n@caption{",
- save_input_text_offset, start_of_end);
- if (i > -1)
- {
- input_text_offset = i + sizeof ("\n@caption{") - 1;
- get_until_in_braces ("\n@end float", &caption);
- input_text_offset = save_input_text_offset;
- }
- else
- caption = "";
- /* ... and the @shortcaption. */
- i = search_forward_until_pos ("\n@shortcaption{",
- save_input_text_offset, start_of_end);
- if (i > -1)
- {
- input_text_offset = i + sizeof ("\n@shortcaption{") - 1;
- get_until_in_braces ("\n@end float", &shortcaption);
- input_text_offset = save_input_text_offset;
- }
- else
- shortcaption = "";
- canon_white (xreflabel);
- canon_white (floattype);
- canon_white (position);
- canon_white (caption);
- canon_white (shortcaption);
- add_new_float (xstrdup (xreflabel),
- xstrdup (caption), xstrdup (shortcaption),
- xstrdup (floattype), xstrdup (position));
- /* Move to the start of the @float so the contents get processed as
- usual. */
- input_text_offset = save_input_text_offset;
- line_number = save_line_number;
- }
- if (html)
- add_html_block_elt ("<div class=\"float\">\n");
- else if (docbook)
- xml_insert_element (FLOAT, START);
- else if (xml)
- {
- xml_insert_element_with_attribute (FLOAT, START,
- "name=\"%s\"", current_float_id ());
- xml_insert_element (FLOATTYPE, START);
- execute_string ("%s", current_float_type ());
- xml_insert_element (FLOATTYPE, END);
- xml_insert_element (FLOATPOS, START);
- execute_string ("%s", current_float_position ());
- xml_insert_element (FLOATPOS, END);
- }
- else
- { /* Info */
- close_single_paragraph ();
- inhibit_paragraph_indentation = 1;
- }
- /* Anchor now. Note that XML documents get their
- anchors with <float name="anchor"> tag. */
- if ((!xml || docbook) && strlen (current_float_id ()) > 0)
- execute_string ("@anchor{%s}", current_float_id ());
- break;
- /* Insertions that are no-ops in info, but do something in TeX. */
- case ifclear:
- case ifdocbook:
- case ifhtml:
- case ifinfo:
- case ifnotdocbook:
- case ifnothtml:
- case ifnotinfo:
- case ifnotplaintext:
- case ifnottex:
- case ifnotxml:
- case ifplaintext:
- case ifset:
- case iftex:
- case ifxml:
- case rawtex:
- if (in_menu)
- no_discard++;
- break;
- case rawdocbook:
- case rawhtml:
- case rawxml:
- raw_output_block++;
- if (raw_output_block > 0)
- {
- xml_no_para = 1;
- escape_html = 0;
- xml_keep_space++;
- }
- {
- /* Some deuglification for improved readability. */
- extern int xml_in_para;
- if (xml && !xml_in_para && xml_indentation_increment > 0)
- add_char ('\n');
- }
- break;
- case defcv:
- case deffn:
- case defivar:
- case defmac:
- case defmethod:
- case defop:
- case defopt:
- case defspec:
- case deftp:
- case deftypecv:
- case deftypefn:
- case deftypefun:
- case deftypeivar:
- case deftypemethod:
- case deftypeop:
- case deftypevar:
- case deftypevr:
- case defun:
- case defvar:
- case defvr:
- inhibit_paragraph_indentation = 1;
- filling_enabled = indented_fill = 1;
- current_indent += default_indentation_increment;
- no_indent = 0;
- if (xml)
- xml_begin_definition ();
- break;
- case flushleft:
- close_single_paragraph ();
- inhibit_paragraph_indentation = 1;
- filling_enabled = indented_fill = no_indent = 0;
- if (html)
- add_html_block_elt ("<div align=\"left\">");
- break;
- case flushright:
- close_single_paragraph ();
- filling_enabled = indented_fill = no_indent = 0;
- inhibit_paragraph_indentation = 1;
- force_flush_right++;
- if (html)
- add_html_block_elt ("<div align=\"right\">");
- break;
- case raggedcenter:
- close_single_paragraph ();
- filling_enabled = indented_fill = 1;
- no_indent = inhibit_paragraph_indentation = 1;
- if (html)
- add_html_block_elt ("<div align=\"center\">");
- break;
- case raggedleft:
- close_single_paragraph ();
- filling_enabled = indented_fill = 1;
- no_indent = inhibit_paragraph_indentation = 1;
- if (html)
- add_html_block_elt ("<div align=\"right\">");
- break;
- case raggedright:
- close_single_paragraph ();
- filling_enabled = indented_fill = 1;
- no_indent = inhibit_paragraph_indentation = 0;
- if (html)
- add_html_block_elt ("<div align=\"left\">");
- break;
- case titlepage:
- xml_insert_element (TITLEPAGE, START);
- break;
- default:
- line_error ("begin_insertion internal error: type=%d", type);
- }
- if (!no_discard)
- discard_until ("\n");
- }
- /* Try to end the insertion with the specified TYPE. With a value of
- `bad_type', TYPE gets translated to match the value currently on top
- of the stack. Otherwise, if TYPE doesn't match the top of the
- insertion stack, give error. */
- static void
- end_insertion (enum insertion_type type)
- {
- enum insertion_type temp_type;
- if (!insertion_level)
- return;
- temp_type = current_insertion_type ();
- if (type == bad_type)
- type = temp_type;
- if (type != temp_type)
- {
- line_error
- (_("`@end' expected `%s', but saw `%s'"),
- insertion_type_pname (temp_type), insertion_type_pname (type));
- return;
- }
- pop_insertion ();
- if (xml)
- {
- switch (type)
- {
- case ifinfo:
- case documentdescription:
- break;
- case quotation:
- xml_insert_quotation ("", END);
- break;
- case example:
- xml_insert_element (EXAMPLE, END);
- if (docbook && current_insertion_type () == floatenv)
- xml_insert_element (FLOATEXAMPLE, END);
- break;
- case smallexample:
- xml_insert_element (SMALLEXAMPLE, END);
- if (docbook && current_insertion_type () == floatenv)
- xml_insert_element (FLOATEXAMPLE, END);
- break;
- case lisp:
- xml_insert_element (LISP, END);
- if (docbook && current_insertion_type () == floatenv)
- xml_insert_element (FLOATEXAMPLE, END);
- break;
- case smalllisp:
- xml_insert_element (SMALLLISP, END);
- if (docbook && current_insertion_type () == floatenv)
- xml_insert_element (FLOATEXAMPLE, END);
- break;
- case cartouche:
- xml_insert_element (CARTOUCHE, END);
- break;
- case format:
- if (docbook && xml_in_bookinfo && xml_in_abstract)
- {
- xml_insert_element (ABSTRACT, END);
- xml_in_abstract = 0;
- }
- else
- xml_insert_element (FORMAT, END);
- break;
- case smallformat:
- xml_insert_element (SMALLFORMAT, END);
- break;
- case display:
- xml_insert_element (DISPLAY, END);
- break;
- case smalldisplay:
- xml_insert_element (SMALLDISPLAY, END);
- break;
- case table:
- case ftable:
- case vtable:
- case itemize:
- xml_end_table (type);
- break;
- case enumerate:
- xml_end_enumerate ();
- break;
- case group:
- xml_insert_element (GROUP, END);
- break;
- case titlepage:
- xml_insert_element (TITLEPAGE, END);
- break;
- }
- }
- switch (type)
- {
- /* Insertions which have no effect on paragraph formatting. */
- case copying:
- line_number--;
- break;
- case ifclear:
- case ifdocbook:
- case ifinfo:
- case ifhtml:
- case ifnotdocbook:
- case ifnothtml:
- case ifnotinfo:
- case ifnotplaintext:
- case ifnottex:
- case ifnotxml:
- case ifplaintext:
- case ifset:
- case iftex:
- case ifxml:
- case rawtex:
- case titlepage:
- break;
- case rawdocbook:
- case rawhtml:
- case rawxml:
- raw_output_block--;
- if (raw_output_block <= 0)
- {
- xml_no_para = 0;
- escape_html = 1;
- xml_keep_space--;
- }
- if ((xml || html)
- && output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- break;
- case detailmenu:
- if (xml)
- xml_insert_element (DETAILMENU, END);
- in_detailmenu--; /* No longer hacking menus. */
- if (!in_menu)
- {
- if (!no_headers)
- close_insertion_paragraph ();
- }
- break;
- case direntry: /* Eaten if html. */
- insert_string ("END-INFO-DIR-ENTRY\n\n");
- close_insertion_paragraph ();
- break;
- case documentdescription:
- if (xml)
- insert_string (document_description);
- xml_insert_element (DOCUMENTDESCRIPTION, END);
- break;
-
- case menu:
- in_menu--; /* No longer hacking menus. */
- if (html && !no_headers)
- add_html_block_elt ("</ul>\n");
- else if (!no_headers && !xml)
- close_insertion_paragraph ();
- break;
- case multitable:
- end_multitable ();
- break;
- case enumerate:
- stop_enumerating ();
- close_insertion_paragraph ();
- current_indent -= default_indentation_increment;
- if (html)
- add_html_block_elt ("</ol>\n");
- break;
- case flushleft:
- if (html)
- add_html_block_elt ("</div>\n");
- close_insertion_paragraph ();
- break;
- case cartouche:
- if (html)
- add_html_block_elt ("</td></tr></table>\n");
- close_insertion_paragraph ();
- break;
- case group:
- if (!xml || docbook)
- close_insertion_paragraph ();
- break;
- case floatenv:
- if (xml)
- xml_insert_element (FLOAT, END);
- else
- {
- if (html)
- add_html_block_elt ("<p><strong class=\"float-caption\">");
- else
- close_paragraph ();
- no_indent = 1;
- /* Legend:
- 1) @float Foo,lbl & no caption: Foo 1.1
- 2) @float Foo & no caption: Foo
- 3) @float ,lbl & no caption: 1.1
- 4) @float & no caption: */
- if (!xml && !html)
- indent (current_indent);
- if (strlen (current_float_type ()))
- execute_string ("%s", current_float_type ());
- if (strlen (current_float_id ()) > 0)
- {
- if (strlen (current_float_type ()) > 0)
- add_char (' ');
- add_word (current_float_number ());
- }
- if (strlen (current_float_title ()) > 0)
- {
- if (strlen (current_float_type ()) > 0
- || strlen (current_float_id ()) > 0)
- insert_string (": ");
- execute_string ("%s", current_float_title ());
- }
- /* Indent the following paragraph. */
- inhibit_paragraph_indentation = 0;
- if (html)
- add_word ("</strong></p></div>\n");
- else
- close_paragraph ();
- }
- float_active--;
- break;
- case format:
- case smallformat:
- case display:
- case smalldisplay:
- case example:
- case smallexample:
- case lisp:
- case smalllisp:
- case quotation:
- /* @format and @smallformat are the only fixed_width insertion
- without a change in indentation. */
- if (type != format && type != smallformat && type != quotation)
- current_indent -= example_indentation_increment;
- else if (type == quotation && !html)
- current_indent -= default_indentation_increment;
- if (html)
- { /* The complex code in close_paragraph that kills whitespace
- does not function here, since we've inserted non-whitespace
- (the </whatever>) before it. The indentation already got
- inserted at the end of the last example line, so we have to
- delete it, or browsers wind up showing an extra blank line.
- Furthermore, if we're inside indented environments, we
- might have arbitrarily much indentation, so remove it all. */
- kill_self_indent (-1);
- add_html_block_elt (type == quotation
- ? "</blockquote>\n" : "</pre>\n");
- }
- /* The ending of one of these insertions always marks the
- start of a new paragraph, except for the XML output. */
- if (!xml || docbook)
- close_insertion_paragraph ();
- /* </pre> closes paragraph without messing with </p>. */
- if (html && type != quotation)
- paragraph_is_open = 0;
- break;
- case table:
- case ftable:
- case vtable:
- current_indent -= default_indentation_increment;
- if (html)
- add_html_block_elt ("</dl>\n");
- close_insertion_paragraph ();
- break;
- case itemize:
- current_indent -= default_indentation_increment;
- if (html)
- add_html_block_elt ("</ul>\n");
- close_insertion_paragraph ();
- break;
- case flushright:
- force_flush_right--;
- if (html)
- add_html_block_elt ("</div>\n");
- close_insertion_paragraph ();
- break;
- case raggedcenter:
- case raggedleft:
- case raggedright:
- if (html)
- add_html_block_elt ("</div>\n");
- close_insertion_paragraph ();
- break;
- /* Handle the @defun insertions with this default clause. */
- default:
- {
- int base_type;
- if (type < defcv || type > defvr)
- line_error ("end_insertion internal error: type=%d", type);
-
- base_type = get_base_type (type);
- switch (base_type)
- {
- case deffn:
- case defvr:
- case deftp:
- case deftypecv:
- case deftypefn:
- case deftypevr:
- case defcv:
- case defop:
- case deftypemethod:
- case deftypeop:
- case deftypeivar:
- if (html)
- {
- if (paragraph_is_open)
- add_html_block_elt ("</p>");
- /* close the div and blockquote which has been opened in defun.c */
- if (!rollback_empty_tag ("blockquote"))
- add_html_block_elt ("</blockquote>");
- add_html_block_elt ("</div>\n");
- }
- if (xml)
- xml_end_definition ();
- break;
- } /* switch (base_type)... */
-
- current_indent -= default_indentation_increment;
- close_insertion_paragraph ();
- }
- break;
-
- }
- if (current_indent < 0)
- line_error ("end_insertion internal error: current indent=%d",
- current_indent);
- }
- /* Insertions cannot cross certain boundaries, such as node beginnings. In
- code that creates such boundaries, you should call `discard_insertions'
- before doing anything else. It prints the errors for you, and cleans up
- the insertion stack.
- With nonzero SPECIALS_OK argument, allows unmatched
- @if... conditionals, otherwise not. This is because conditionals can
- cross node boundaries. Always happens with the @top node, for example. */
- void
- discard_insertions (int specials_ok)
- {
- int real_line_number = line_number;
- while (insertion_stack)
- {
- if (specials_ok
- && ((ifclear <= insertion_stack->insertion
- && insertion_stack->insertion <= iftex)
- || insertion_stack->insertion == rawdocbook
- || insertion_stack->insertion == rawhtml
- || insertion_stack->insertion == rawxml
- || insertion_stack->insertion == rawtex))
- break;
- else
- {
- const char *offender = insertion_type_pname (insertion_stack->insertion);
- file_line_error (insertion_stack->filename,
- insertion_stack->line_number,
- _("No matching `%cend %s'"), COMMAND_PREFIX,
- offender);
- pop_insertion ();
- }
- }
- line_number = real_line_number;
- }
- /* Insertion (environment) commands. */
- void
- cm_quotation (void)
- {
- /* We start the blockquote element in the insertion. */
- begin_insertion (quotation);
- }
- void
- cm_example (void)
- {
- if (docbook && current_insertion_type () == floatenv)
- xml_begin_docbook_float (FLOATEXAMPLE);
- if (xml)
- {
- /* Rollback previous newlines. These occur between
- </para> and <example>. */
- if (output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- xml_insert_element (EXAMPLE, START);
- /* Make sure example text is starting on a new line
- for improved readability. */
- if (docbook)
- add_char ('\n');
- }
- begin_insertion (example);
- }
- void
- cm_smallexample (void)
- {
- if (docbook && current_insertion_type () == floatenv)
- xml_begin_docbook_float (FLOATEXAMPLE);
- if (xml)
- {
- /* See cm_example comments about newlines. */
- if (output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- xml_insert_element (SMALLEXAMPLE, START);
- if (docbook)
- add_char ('\n');
- }
- begin_insertion (smallexample);
- }
- void
- cm_lisp (void)
- {
- if (docbook && current_insertion_type () == floatenv)
- xml_begin_docbook_float (FLOATEXAMPLE);
- if (xml)
- {
- /* See cm_example comments about newlines. */
- if (output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- xml_insert_element (LISP, START);
- if (docbook)
- add_char ('\n');
- }
- begin_insertion (lisp);
- }
- void
- cm_smalllisp (void)
- {
- if (docbook && current_insertion_type () == floatenv)
- xml_begin_docbook_float (FLOATEXAMPLE);
- if (xml)
- {
- /* See cm_example comments about newlines. */
- if (output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- xml_insert_element (SMALLLISP, START);
- if (docbook)
- add_char ('\n');
- }
- begin_insertion (smalllisp);
- }
- void
- cm_cartouche (void)
- {
- if (docbook && current_insertion_type () == floatenv)
- xml_begin_docbook_float (CARTOUCHE);
- if (xml)
- xml_insert_element (CARTOUCHE, START);
- begin_insertion (cartouche);
- }
- void
- cm_copying (void)
- {
- begin_insertion (copying);
- }
- /* Not an insertion, despite the name, but it goes with cm_copying. */
- void
- cm_insert_copying (void)
- {
- if (!copying_text)
- {
- warning ("@copying not used before %s", command);
- return;
- }
- /* It is desirable that @copying is set early in the input file. For
- Info output, we write the copying text out right away, and thus it
- may well be the first thing in the output, and we want the file
- header first. The special case in add_char has to check for
- executing_string, so it won't be effective. Thus, do it explicitly. */
- output_head ();
- execute_string ("%s", copying_text);
- if (!xml && !html)
- {
- add_word ("\n\n");
- /* Update output_position so that the node positions in the tag
- tables will take account of the copying text. */
- flush_output ();
- }
- }
- void
- cm_format (void)
- {
- if (xml)
- {
- if (docbook && xml_in_bookinfo)
- {
- xml_insert_element (ABSTRACT, START);
- xml_in_abstract = 1;
- }
- else
- {
- /* See cm_example comments about newlines. */
- if (output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- xml_insert_element (FORMAT, START);
- if (docbook)
- add_char ('\n');
- }
- }
- begin_insertion (format);
- }
- void
- cm_smallformat (void)
- {
- if (xml)
- {
- /* See cm_example comments about newlines. */
- if (output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- xml_insert_element (SMALLFORMAT, START);
- if (docbook)
- add_char ('\n');
- }
- begin_insertion (smallformat);
- }
- void
- cm_display (void)
- {
- if (xml)
- {
- /* See cm_example comments about newlines. */
- if (output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- xml_insert_element (DISPLAY, START);
- if (docbook)
- add_char ('\n');
- }
- begin_insertion (display);
- }
- void
- cm_smalldisplay (void)
- {
- if (xml)
- {
- /* See cm_example comments about newlines. */
- if (output_paragraph_offset > 0
- && output_paragraph[output_paragraph_offset-1] == '\n')
- output_paragraph_offset--;
- xml_insert_element (SMALLDISPLAY, START);
- if (docbook)
- add_char ('\n');
- }
- begin_insertion (smalldisplay);
- }
- void
- cm_direntry (void)
- {
- if (html || xml || no_headers)
- command_name_condition ();
- else
- begin_insertion (direntry);
- }
- void
- cm_documentdescription (void)
- {
- if (html)
- begin_insertion (documentdescription);
- else if (xml)
- {
- xml_insert_element (DOCUMENTDESCRIPTION, START);
- begin_insertion (documentdescription);
- }
- else
- command_name_condition ();
- }
- void
- cm_itemize (void)
- {
- begin_insertion (itemize);
- }
- /* Start an enumeration insertion of type TYPE. If the user supplied
- no argument on the line, then use DEFAULT_STRING as the initial string. */
- static void
- do_enumeration (enum insertion_type type, char *default_string)
- {
- get_until_in_line (0, ".", &enumeration_arg);
- canon_white (enumeration_arg);
- if (!*enumeration_arg)
- {
- free (enumeration_arg);
- enumeration_arg = xstrdup (default_string);
- }
- if (!isdigit (*enumeration_arg) && !isletter (*enumeration_arg))
- {
- warning (_("%s requires letter or digit"), insertion_type_pname (type));
- switch (type)
- {
- case enumerate:
- default_string = "1";
- break;
- }
- enumeration_arg = xstrdup (default_string);
- }
- begin_insertion (type);
- }
- void
- cm_enumerate (void)
- {
- do_enumeration (enumerate, "1");
- }
- /* Handle verbatim environment:
- find_end_verbatim == 0: process until end of file
- find_end_verbatim != 0: process until 'COMMAND_PREFIXend verbatim'
- or end of file
- No indentation is inserted: this is verbatim after all.
- If you want indentation, enclose @verbatim in @example.
- Thus, we cannot simply copy the input to the output, since the
- verbatim environment may be encapsulated in an @example environment,
- for example. */
- void
- handle_verbatim_environment (int find_end_verbatim)
- {
- int character;
- int seen_end = 0;
- int save_filling_enabled = filling_enabled;
- int save_inhibit_paragraph_indentation = inhibit_paragraph_indentation;
- if (!insertion_stack)
- close_single_paragraph (); /* no blank lines if not at outer level */
- inhibit_paragraph_indentation = 1;
- filling_enabled = 0;
- in_fixed_width_font++;
- last_char_was_newline = 0;
- if (html)
- { /* If inside @example, we'll be preceded by the indentation
- already. Browsers will ignore those spaces because we're about
- to start another <pre> (don't ask me). So, wipe them out for
- cleanliness, and re-insert. */
- int i;
- kill_self_indent (default_indentation_increment);
- add_html_block_elt ("<pre class=\"verbatim\">");
- for (i = current_indent; i > 0; i--)
- add_char (' ');
- }
- else if (xml)
- {
- xml_insert_element (VERBATIM, START);
- }
- if (find_end_verbatim)
- { /* Ignore the remainder of the @verbatim line. */
- char *junk;
- get_rest_of_line (0, &junk);
- free (junk);
- }
-
- while (input_text_offset < input_text_length)
- {
- character = curchar ();
- if (character == '\n')
- line_number++;
- /* Assume no newlines in END_VERBATIM. */
- else if (find_end_verbatim && (character == COMMAND_PREFIX) /* @ */
- && (input_text_length - input_text_offset > sizeof (END_VERBATIM))
- && !strncmp (&input_text[input_text_offset+1], END_VERBATIM,
- sizeof (END_VERBATIM)-1))
- {
- input_text_offset += sizeof (END_VERBATIM);
- seen_end = 1;
- break;
- }
- if (html && character == '&' && escape_html)
- add_word ("&");
- else if (html && character == '<' && escape_html)
- add_word ("<");
- else
- add_char (character);
- input_text_offset++;
- }
- if (find_end_verbatim && !seen_end)
- warning (_("end of file inside verbatim block"));
- if (html)
- { /* See comments in example case above. */
- kill_self_indent (default_indentation_increment);
- add_word ("</pre>");
- }
- else if (xml)
- {
- xml_insert_element (VERBATIM, END);
- }
-
- in_fixed_width_font--;
- filling_enabled = save_filling_enabled;
- inhibit_paragraph_indentation = save_inhibit_paragraph_indentation;
- }
- void
- cm_verbatim (void)
- {
- handle_verbatim_environment (1);
- }
- void
- cm_table (void)
- {
- begin_insertion (table);
- }
- void
- cm_multitable (void)
- {
- begin_insertion (multitable); /* @@ */
- }
- void
- cm_ftable (void)
- {
- begin_insertion (ftable);
- }
- void
- cm_vtable (void)
- {
- begin_insertion (vtable);
- }
- void
- cm_group (void)
- {
- begin_insertion (group);
- }
- /* Insert raw HTML (no escaping of `<' etc.). */
- void
- cm_html (int arg)
- {
- if (process_html)
- begin_insertion (rawhtml);
- else
- command_name_condition ();
- }
- void
- cm_xml (int arg)
- {
- if (process_xml)
- begin_insertion (rawxml);
- else
- command_name_condition ();
- }
- void
- cm_docbook (int arg)
- {
- if (process_docbook)
- begin_insertion (rawdocbook);
- else
- command_name_condition ();
- }
- void
- cm_ifdocbook (void)
- {
- if (process_docbook)
- begin_insertion (ifdocbook);
- else
- command_name_condition ();
- }
- void
- cm_ifnotdocbook (void)
- {
- if (!process_docbook)
- begin_insertion (ifnotdocbook);
- else
- command_name_condition ();
- }
- void
- cm_ifhtml (void)
- {
- if (process_html)
- begin_insertion (ifhtml);
- else
- command_name_condition ();
- }
- void
- cm_ifnothtml (void)
- {
- if (!process_html)
- begin_insertion (ifnothtml);
- else
- command_name_condition ();
- }
- void
- cm_ifinfo (void)
- {
- if (process_info)
- begin_insertion (ifinfo);
- else
- command_name_condition ();
- }
- void
- cm_ifnotinfo (void)
- {
- if (!process_info)
- begin_insertion (ifnotinfo);
- else
- command_name_condition ();
- }
- void
- cm_ifplaintext (void)
- {
- if (process_plaintext)
- begin_insertion (ifplaintext);
- else
- command_name_condition ();
- }
- void
- cm_ifnotplaintext (void)
- {
- if (!process_plaintext)
- begin_insertion (ifnotplaintext);
- else
- command_name_condition ();
- }
- void
- cm_tex (void)
- {
- if (process_tex)
- begin_insertion (rawtex);
- else
- command_name_condition ();
- }
- void
- cm_iftex (void)
- {
- if (process_tex)
- begin_insertion (iftex);
- else
- command_name_condition ();
- }
- void
- cm_ifnottex (void)
- {
- if (!process_tex)
- begin_insertion (ifnottex);
- else
- command_name_condition ();
- }
- void
- cm_ifxml (void)
- {
- if (process_xml)
- begin_insertion (ifxml);
- else
- command_name_condition ();
- }
- void
- cm_ifnotxml (void)
- {
- if (!process_xml)
- begin_insertion (ifnotxml);
- else
- command_name_condition ();
- }
- /* Generic xrefable block with a caption. */
- void
- cm_float (void)
- {
- begin_insertion (floatenv);
- }
- void
- cm_caption (int arg)
- {
- char *temp;
- /* This is a no_op command for most formats, as we handle it during @float
- insertion. For XML though, we handle it here to keep document structure
- as close as possible, to the Texinfo source. */
- /* Everything is already handled at START. */
- if (arg == END)
- return;
- /* Check if it's mislocated. */
- if (current_insertion_type () != floatenv)
- line_error (_("@%s not meaningful outside `@float' environment"), command);
- get_until_in_braces ("\n@end float", &temp);
- if (xml)
- {
- int elt = STREQ (command, "shortcaption") ? SHORTCAPTION : CAPTION;
- xml_insert_element (elt, START);
- if (!docbook)
- execute_string ("%s", temp);
- xml_insert_element (elt, END);
- }
- free (temp);
- }
- /* Begin an insertion where the lines are not filled or indented. */
- void
- cm_flushleft (void)
- {
- begin_insertion (flushleft);
- }
- /* Begin an insertion where the lines are not filled, and each line is
- forced to the right-hand side of the page. */
- void
- cm_flushright (void)
- {
- begin_insertion (flushright);
- }
- void
- cm_menu (void)
- {
- if (current_node == NULL && !macro_expansion_output_stream)
- {
- warning (_("@menu seen before first @node, creating `Top' node"));
- warning (_("perhaps your @top node should be wrapped in @ifnottex rather than @ifinfo?"));
- /* Include @top command so we can construct the implicit node tree. */
- execute_string ("@node top\n@top Top\n");
- }
- begin_insertion (menu);
- }
- void
- cm_detailmenu (void)
- {
- if (current_node == NULL && !macro_expansion_output_stream)
- { /* Problems anyway, @detailmenu should always be inside @menu. */
- warning (_("@detailmenu seen before first node, creating `Top' node"));
- execute_string ("@node top\n@top Top\n");
- }
- begin_insertion (detailmenu);
- }
- void
- cm_raggedcenter (void)
- {
- begin_insertion (raggedcenter);
- }
- void
- cm_raggedleft (void)
- {
- begin_insertion (raggedleft);
- }
- void
- cm_raggedright (void)
- {
- begin_insertion (raggedright);
- }
- /* Title page commands. */
- void
- cm_titlepage (void)
- {
- titlepage_cmd_present = 1;
- if (xml && !docbook)
- begin_insertion (titlepage);
- else
- command_name_condition ();
- }
- void
- cm_author (void)
- {
- char *rest;
- get_rest_of_line (1, &rest);
- if (is_in_insertion_of_type (quotation))
- {
- if (html)
- add_word_args ("— %s", rest);
- else if (docbook)
- {
- /* FIXME Ideally, we should use an attribution element,
- but they are supposed to be at the start of quotation
- blocks. So to avoid looking ahead mess, let's just
- use mdash like HTML for now. */
- xml_insert_entity ("mdash");
- add_word (rest);
- }
- else if (xml)
- {
- xml_insert_element (AUTHOR, START);
- add_word (rest);
- xml_insert_element (AUTHOR, END);
- }
- else
- add_word_args ("-- %s", rest);
- }
- else if (is_in_insertion_of_type (titlepage))
- {
- if (xml && !docbook)
- {
- xml_insert_element (AUTHOR, START);
- add_word (rest);
- xml_insert_element (AUTHOR, END);
- }
- }
- else
- line_error (_("@%s not meaningful outside `@titlepage' and `@quotation' environments"),
- command);
- free (rest);
- }
- void
- cm_titlepage_cmds (void)
- {
- char *rest;
- get_rest_of_line (1, &rest);
- if (!is_in_insertion_of_type (titlepage))
- line_error (_("@%s not meaningful outside `@titlepage' environment"),
- command);
- if (xml && !docbook)
- {
- int elt = 0;
- if (STREQ (command, "title"))
- elt = BOOKTITLE;
- else if (STREQ (command, "subtitle"))
- elt = BOOKSUBTITLE;
- xml_insert_element (elt, START);
- add_word (rest);
- xml_insert_element (elt, END);
- }
- free (rest);
- }
- /* End existing insertion block. */
- void
- cm_end (void)
- {
- char *temp;
- enum insertion_type type;
- get_rest_of_line (0, &temp);
- if (!insertion_level)
- {
- line_error (_("Unmatched `%c%s'"), COMMAND_PREFIX, command);
- return;
- }
- if (temp[0] == 0)
- line_error (_("`%c%s' needs something after it"), COMMAND_PREFIX, command);
- type = find_type_from_name (temp);
- if (type == bad_type)
- {
- line_error (_("Bad argument `%s' to `@%s', using `%s'"),
- temp, command, insertion_type_pname (current_insertion_type ()));
- }
- if (xml && type == menu) /* fixme */
- {
- xml_end_menu ();
- }
- end_insertion (type);
- free (temp);
- }
- /* @itemx, @item. */
- static int itemx_flag = 0;
- /* Return whether CMD takes a brace-delimited {arg}. */
- int
- command_needs_braces (char *cmd)
- {
- int i;
- for (i = 0; command_table[i].name; i++)
- {
- if (STREQ (command_table[i].name, cmd))
- return command_table[i].argument_in_braces == BRACE_ARGS;
- }
- return 0; /* macro or alias */
- }
- void
- cm_item (void)
- {
- char *rest_of_line, *item_func;
- /* Can only hack "@item" while inside of an insertion. */
- if (insertion_level)
- {
- INSERTION_ELT *stack = insertion_stack;
- int original_input_text_offset;
- skip_whitespace ();
- original_input_text_offset = input_text_offset;
- get_rest_of_line (0, &rest_of_line);
- item_func = current_item_function ();
- /* Do the right thing depending on which insertion function is active. */
- switch_top:
- switch (stack->insertion)
- {
- case multitable:
- multitable_item ();
- /* Support text directly after the @item. */
- if (*rest_of_line)
- {
- line_number--;
- input_text_offset = original_input_text_offset;
- }
- break;
- case ifclear:
- case ifhtml:
- case ifinfo:
- case ifnothtml:
- case ifnotinfo:
- case ifnotplaintext:
- case ifnottex:
- case ifnotxml:
- case ifplaintext:
- case ifset:
- case iftex:
- case ifxml:
- case rawdocbook:
- case rawhtml:
- case rawxml:
- case rawtex:
- case tex:
- case cartouche:
- stack = stack->next;
- if (!stack)
- goto no_insertion;
- else
- goto switch_top;
- break;
- case menu:
- case quotation:
- case example:
- case smallexample:
- case lisp:
- case smalllisp:
- case format:
- case smallformat:
- case display:
- case smalldisplay:
- case group:
- line_error (_("@%s not meaningful inside `@%s' block"),
- command,
- insertion_type_pname (current_insertion_type ()));
- break;
- case itemize:
- case enumerate:
- if (itemx_flag)
- {
- line_error (_("@itemx not meaningful inside `%s' block"),
- insertion_type_pname (current_insertion_type ()));
- }
- else
- {
- if (html)
- add_html_block_elt ("<li>");
- else if (xml)
- xml_begin_item ();
- else
- {
- start_paragraph ();
- kill_self_indent (-1);
- filling_enabled = indented_fill = 1;
- if (current_item_function ())
- {
- indent (current_indent - 2);
- /* The item marker can be given with or without
- braces -- @bullet and @bullet{} are both ok.
- Or it might be something that doesn't take
- braces at all, such as "o" or "#" or "@ ".
- Thus, only supply braces if the item marker is
- a command, they haven't supplied braces
- themselves, and we know it needs them. */
- if (item_func && *item_func)
- {
- if (*item_func == COMMAND_PREFIX
- && item_func[strlen (item_func) - 1] != '}'
- && command_needs_braces (item_func + 1))
- execute_string ("%s{}", item_func);
- else
- execute_string ("%s", item_func);
- }
- insert (' ');
- }
- else
- enumerate_item ();
- /* Special hack. This makes `close_paragraph' a no-op until
- `start_paragraph' has been called. */
- must_start_paragraph = 1;
- }
- /* Handle text directly after the @item. */
- if (*rest_of_line)
- {
- line_number--;
- input_text_offset = original_input_text_offset;
- }
- }
- break;
- case table:
- case ftable:
- case vtable:
- if (html)
- { /* If nothing has been output since the last <dd>,
- remove the empty <dd> element. Some browsers render
- an extra empty line for <dd><dt>, which makes @itemx
- conversion look ugly. */
- rollback_empty_tag ("dd");
- /* Force the browser to render one blank line before
- each new @item in a table. But don't do that if
- this is the first <dt> after the <dl>, or if we are
- converting @itemx.
- Note that there are some browsers which ignore <br>
- in this context, but I cannot find any way to force
- them all render exactly one blank line. */
- if (!itemx_flag && html_deflist_has_term)
- add_html_block_elt ("<br>");
- /* We are about to insert a <dt>, so this <dl> has a term.
- Feel free to insert a <br> next time. :) */
- html_deflist_has_term = 1;
-
- add_html_block_elt ("<dt>");
- if (item_func && *item_func)
- execute_string ("%s{%s}", item_func, rest_of_line);
- else
- execute_string ("%s", rest_of_line);
- if (current_insertion_type () == ftable)
- execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
- if (current_insertion_type () == vtable)
- execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
- add_html_block_elt ("<dd>");
- }
- else if (xml) /* && docbook)*/ /* 05-08 */
- {
- xml_begin_table_item ();
- if (!docbook && current_insertion_type () == ftable)
- execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
- if (!docbook && current_insertion_type () == vtable)
- execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
- if (item_func && *item_func)
- execute_string ("%s{%s}", item_func, rest_of_line);
- else
- execute_string ("%s", rest_of_line);
- xml_continue_table_item ();
- }
- else
- {
- /* We need this to determine if we have two @item's in a row
- (see test just below). */
- static int last_item_output_position = 0;
- /* Get rid of extra characters. */
- kill_self_indent (-1);
- /* If we have one @item followed directly by another @item,
- we need to insert a blank line. This is not true for
- @itemx, though. */
- if (!itemx_flag && last_item_output_position == output_position)
- insert ('\n');
- /* `close_paragraph' almost does what we want. The problem
- is when paragraph_is_open, and last_char_was_newline, and
- the last newline has been turned into a space, because
- filling_enabled. I handle it here. */
- if (last_char_was_newline && filling_enabled &&
- paragraph_is_open)
- insert ('\n');
- close_paragraph ();
- #if defined (INDENT_PARAGRAPHS_IN_TABLE)
- /* Indent on a new line, but back up one indentation level. */
- {
- int save = inhibit_paragraph_indentation;
- inhibit_paragraph_indentation = 1;
- /* At this point, inserting any non-whitespace character will
- force the existing indentation to be output. */
- add_char ('i');
- inhibit_paragraph_indentation = save;
- }
- #else /* !INDENT_PARAGRAPHS_IN_TABLE */
- add_char ('i');
- #endif /* !INDENT_PARAGRAPHS_IN_TABLE */
- output_paragraph_offset--;
- kill_self_indent (default_indentation_increment + 1);
- /* Add item's argument to the line. */
- filling_enabled = 0;
- if (item_func && *item_func)
- execute_string ("%s{%s}", item_func, rest_of_line);
- else
- execute_string ("%s", rest_of_line);
- if (current_insertion_type () == ftable)
- execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line);
- else if (current_insertion_type () == vtable)
- execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line);
- /* Start a new line, and let start_paragraph ()
- do the indenting of it for you. */
- close_single_paragraph ();
- indented_fill = filling_enabled = 1;
- last_item_output_position = output_position;
- }
- }
- free (rest_of_line);
- }
- else
- {
- no_insertion:
- line_error (_("%c%s found outside of an insertion block"),
- COMMAND_PREFIX, command);
- }
- }
- void
- cm_itemx (void)
- {
- itemx_flag++;
- cm_item ();
- itemx_flag--;
- }
- int headitem_flag = 0;
- void
- cm_headitem (void)
- {
- headitem_flag = 1;
- cm_item ();
- }
|