📄 makeinfo.c
字号:
} return (count);}enum insertion_type{ menu, quotation, lisp, example, smallexample, display, itemize, format, enumerate, table, group, ifinfo, defun, defvar, defopt, deffn, defspec, defmac, bad_type};char *insertion_type_names[] = { "menu", "quotation", "lisp", "example", "smallexample", "display", "itemize", "format", "enumerate", "table", "group", "ifinfo", "defun", "defvar", "defopt", "deffn", "defspec", "defmac",};int insertion_level = 0;typedef struct istack_elt{ struct istack_elt *next; char *item_function; int line_number; int filling_enabled; int indented_fill; enum insertion_type insertion; int inhibited;} INSERTION_ELT;INSERTION_ELT *insertion_stack = (INSERTION_ELT *) NULL;init_insertion_stack (){ insertion_stack = (INSERTION_ELT *) NULL;}/* Return the type of the current insertion. */enum insertion_typecurrent_insertion_type (){ if (!insertion_level) return (bad_type); else return (insertion_stack->insertion);}/* Return a pointer to the string which is the function to wrap around items. */char *current_item_function (){ if (!insertion_level) return ((char *) NULL); else return (insertion_stack->item_function);}char *get_item_function (){ char *item_function; get_until ("\n", &item_function); canon_white (item_function); return (item_function);} /* Push the state of the current insertion on the stack. */push_insertion (type, item_function) enum insertion_type type; char *item_function;{ INSERTION_ELT *new = (INSERTION_ELT *) 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->inhibited = inhibit_paragraph_indentation; new->next = insertion_stack; insertion_stack = new; insertion_level++;} /* Pop the value on top of the insertion stack into the global variables. */pop_insertion (){ INSERTION_ELT *temp = insertion_stack; if (temp == (INSERTION_ELT *) NULL) return; inhibit_paragraph_indentation = temp->inhibited; filling_enabled = insertion_stack->filling_enabled; indented_fill = insertion_stack->indented_fill; free_and_clear (&(temp->item_function)); insertion_stack = insertion_stack->next; free (temp); insertion_level--;} /* Return a pointer to the print name of this enumerated type. */char *insertion_type_pname (type) enum insertion_type type;{ if ((int) type < (int) bad_type) 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_typefind_type_from_name (name) char *name;{ int index = 0; while (index < (int) bad_type) { if (stricmp (name, insertion_type_names[index]) == 0) return (enum insertion_type) index; index++; } return (bad_type);}do_nothing (){}intdefun_insertion (type) enum insertion_type type;{ return (type == defun || type == defvar || type == defopt || type == deffn || type == defspec || type == defmac);}/* Non-zero means that we are currently hacking the insides of an insertion which would use a fixed width font. */int in_fixed_width_font = 0;/* 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. */begin_insertion (type) enum insertion_type type;{ int no_discard = 0; close_paragraph (); if (defun_insertion (type)) { push_insertion (type, savestring ("")); no_discard = 1; } else push_insertion (type, get_item_function ()); filling_enabled = false; /* the general case for insertions. */ inhibit_paragraph_indentation = 1; no_indent = false; switch (type) { case menu: add_word ("* Menu:\n"); in_menu++; discard_until ("\n"); input_text_offset--; /* discard_until () has already counted the newline. Discount it. */ line_number--; return; /* I think @quotation is meant to do filling. If you don't want filling, then use @example. */ case quotation: last_char_was_newline = 0; indented_fill = filling_enabled = true; current_indent += default_indentation_increment; break; /* Just like @example, but no indentation. */ case format: in_fixed_width_font++; break; case display: case example: case smallexample: case lisp: last_char_was_newline = 0; current_indent += default_indentation_increment; in_fixed_width_font++; break; case table: case itemize: current_indent += default_indentation_increment; filling_enabled = indented_fill = true; /* 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 = savestring ("*"); } } break; case enumerate: inhibit_paragraph_indentation = 0; current_indent += default_indentation_increment; start_numbering (1); filling_enabled = indented_fill = true; break; case group: inhibit_paragraph_indentation = 0; break; case ifinfo: /* Undo whatever we just did. This is a no-op. */ inhibit_paragraph_indentation = 0; filling_enabled = insertion_stack->filling_enabled; indented_fill = insertion_stack->indented_fill; break; case defun: case defvar: case defopt: case deffn: case defspec: case defmac: filling_enabled = indented_fill = true; current_indent += default_indentation_increment; break; } if (!no_discard) discard_until ("\n");}/* Try to end the quotation with the specified type. Like begin_insertion (), this uses a giant switch statement as well. A big difference is that you *must* pass a valid type to this function, and a value of bad_type gets translated to match the value currently on top of the stack. If, however, the value passed is a valid type, and it doesn't match the top of the stack, then we produce an error. Should fix this, somewhat unclean. */end_insertion (type) 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 ("Expected `%s', but saw `%s'. Token unread", insertion_type_pname (temp_type), insertion_type_pname (type)); return; } pop_insertion (); switch (type) { case menu: in_menu--; /* no longer hacking menus. */ break; case enumerate: stop_numbering (); current_indent -= default_indentation_increment; break; case group: case ifinfo: break; case format: case example: case smallexample: case display: case lisp: in_fixed_width_font--; current_indent -= default_indentation_increment; break; default: current_indent -= default_indentation_increment; break; } close_paragraph ();}/* 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. */discard_insertions (){ int real_line_number = line_number; while (insertion_stack) { if (insertion_stack->insertion == ifinfo) break; else { char *offender = (char *) insertion_type_pname (insertion_stack->insertion); line_number = insertion_stack->line_number; line_error ("This `%s' doesn't have a matching `%cend %s'", offender, COMMAND_PREFIX, offender); pop_insertion (); } } line_number = real_line_number;}/* 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_ns 100int number_stack[max_ns];int number_offset = 0;int the_current_number = 0;start_numbering (at_number){ if (number_offset + 1 == max_ns) { line_error ("Enumeration stack overflow"); return; } number_stack[number_offset++] = the_current_number; the_current_number = at_number;}stop_numbering (){ the_current_number = number_stack[--number_offset]; if (number_offset < 0) number_offset = 0;} /* Place a number into the output stream. */number_item (){ char temp[10]; sprintf (temp, "%d. ", the_current_number); indent (output_column += (current_indent - strlen (temp))); add_word (temp); the_current_number++;}/* The actual commands themselves. *//* Commands which insert themselves. */insert_self (){ add_word (command);}/* Force line break */cm_asterisk (){ /* Force a line break in the output. */ insert ('\n'); indent (output_column = current_indent);}/* Insert ellipsis. */cm_dots (arg) int arg;{ if (arg == START) add_word ("...");}cm_bullet (arg) int arg;{ if (arg == START) add_char ('*');}cm_minus (arg) int arg;{ if (arg == START) add_char ('-');}/* Insert "TeX". */cm_TeX (arg) int arg;{ if (arg == START) add_word ("TeX");}cm_copyright (arg) int arg;{ if (arg == START) add_word ("(C)");}cm_code (arg) int arg;{ extern int printing_index; if (printing_index) return; if (arg == START) add_char ('`'); else add_word ("'");}cm_samp (arg) int arg;{ cm_code (arg);}cm_file (arg) int arg;{ cm_code (arg);}cm_kbd (arg) int arg;{ cm_code (arg);}cm_key (arg) int arg;{} /* Convert the character at position-1 into CTL. */cm_ctrl (arg, position) int arg, position;{ if (arg == END) output_paragraph[position - 1] = CTL (output_paragraph[position - 1]);}/* Small Caps in makeinfo just does all caps. */cm_sc (arg, start_pos, end_pos) int arg, start_pos, end_pos;{ if (arg == END) { while (start_pos < end_pos) { output_paragraph[start_pos] = coerce_to_upper (output_paragraph[start_pos]); start_pos++; } }}/* @var in makeinfo just uppercases the text. */cm_var (arg, start_pos, end_pos) int arg, start_pos, end_pos;{ if (arg == END) { while (start_pos < end_pos) { output_paragraph[start_pos] = coerce_to_upper (output_paragraph[start_pos]); start_pos++; } }}cm_dfn (arg, position) int arg, position;{ add_char ('"');}cm_emph (arg) int arg;{ add_char ('*');}cm_strong (arg, position) int arg, position;{ cm_emph (arg);}cm_cite (arg, position) int arg, position;{ if (arg == START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -