Back to index

tetex-bin  3.0
Classes | Defines | Typedefs | Functions | Variables
footnote.c File Reference
#include "system.h"
#include "footnote.h"
#include "macro.h"
#include "makeinfo.h"
#include "node.h"
#include "xml.h"
#include "xref.h"

Go to the source code of this file.

Classes

struct  fn

Defines

#define separate_node   0
#define end_node   1

Typedefs

typedef struct fn FN

Functions

int set_footnote_style (char *string)
void cm_footnotestyle (void)
static void remember_note (char *marker, char *note)
static void free_pending_notes (void)
void cm_footnote (void)
void output_pending_notes (void)

Variables

int footnote_style_preset = 0
int current_footnote_number = 1
int number_footnotes = 1
int already_outputting_pending_notes = 0
int footnote_style = end_node
int first_footnote_this_node = 1
int footnote_count = 0
FNpending_notes = NULL

Class Documentation

struct fn

Definition at line 87 of file footnote.c.

Collaboration diagram for fn:
Class Members
char * marker
struct fn * next
char * note
int number

Define Documentation

#define end_node   1

Definition at line 53 of file footnote.c.

#define separate_node   0

Definition at line 52 of file footnote.c.


Typedef Documentation

typedef struct fn FN

Function Documentation

Definition at line 136 of file footnote.c.

{
  char *marker;
  char *note;

  get_until ("{", &marker);
  canon_white (marker);

  if (macro_expansion_output_stream && !executing_string)
    append_to_expansion_output (input_text_offset + 1); /* include the { */

  /* Read the argument in braces. */
  if (curchar () != '{')
    {
      line_error (_("`%c%s' needs an argument `{...}', not just `%s'"),
                  COMMAND_PREFIX, command, marker);
      free (marker);
      return;
    }
  else
    {
      int len;
      int braces = 1;
      int loc = ++input_text_offset;

      while (braces)
        {
          if (loc == input_text_length)
            {
              line_error (_("No closing brace for footnote `%s'"), marker);
              return;
            }

          if (input_text[loc] == '{')
            braces++;
          else if (input_text[loc] == '}')
            braces--;
          else if (input_text[loc] == '\n')
            line_number++;

          loc++;
        }

      len = (loc - input_text_offset) - 1;
      note = xmalloc (len + 1);
      memcpy (note, &input_text[input_text_offset], len);
      note[len] = 0;
      input_text_offset = loc;
    }

  /* Must write the macro-expanded argument to the macro expansion
     output stream.  This is like the case in index_add_arg.  */
  if (macro_expansion_output_stream && !executing_string)
    {
      /* Calling me_execute_string on a lone } provokes an error, since
         as far as the reader knows there is no matching {.  We wrote
         the { above in the call to append_to_expansion_output. */
      me_execute_string_keep_state (note, "}");
    }

  if (!current_node || !*current_node)
    {
      line_error (_("Footnote defined without parent node"));
      free (marker);
      free (note);
      return;
    }

  /* output_pending_notes is non-reentrant (it uses a global data
     structure pending_notes, which it frees before it returns), and
     TeX doesn't grok footnotes inside footnotes anyway.  Disallow
     that.  */
  if (already_outputting_pending_notes)
    {
      line_error (_("Footnotes inside footnotes are not allowed"));
      free (marker);
      free (note);
      return;
    }

  if (!*marker)
    {
      free (marker);

      if (number_footnotes)
        {
          marker = xmalloc (10);
          sprintf (marker, "%d", current_footnote_number);
        }
      else
        marker = xstrdup ("*");
    }

  if (xml)
    xml_insert_footnote (note);
  else 
    {
  remember_note (marker, note);

  /* fixme: html: footnote processing needs work; we currently ignore
     the style requested; we could clash with a node name of the form
     `fn-<n>', though that's unlikely. */
  if (html)
    {
      /* Hyperlink also serves as an anchor (mnemonic: fnd is footnote
         definition.)  */
      add_html_elt ("<a rel=\"footnote\" href=");
      add_word_args ("\"#fn-%d\" name=\"fnd-%d\"><sup>%s</sup></a>",
                   current_footnote_number, current_footnote_number,
                     marker);
    }
  else
    /* Your method should at least insert MARKER. */
    switch (footnote_style)
      {
      case separate_node:
        add_word_args ("(%s)", marker);
        execute_string (" (*note %s-Footnote-%d::)",
                        current_node, current_footnote_number);
        if (first_footnote_this_node)
          {
            char *temp_string, *expanded_ref;

            temp_string = xmalloc (strlen (current_node)
                                   + strlen ("-Footnotes") + 1);

            strcpy (temp_string, current_node);
            strcat (temp_string, "-Footnotes");
            expanded_ref = expansion (temp_string, 0);
            remember_node_reference (expanded_ref, line_number,
                                     followed_reference);
            free (temp_string);
            free (expanded_ref);
            first_footnote_this_node = 0;
          }
        break;

      case end_node:
        add_word_args ("(%s)", marker);
        break;

      default:
        break;
      }
  current_footnote_number++;
    }
  free (marker);
  free (note);
}

Here is the call graph for this function:

Definition at line 74 of file footnote.c.

{
  char *arg;

  get_rest_of_line (1, &arg);

  /* If set on command line, do not change the footnote style.  */
  if (!footnote_style_preset && set_footnote_style (arg) != 0)
    line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command);

  free (arg);
}

Here is the call graph for this function:

static void free_pending_notes ( void  ) [static]

Definition at line 114 of file footnote.c.

{
  FN *temp;

  while ((temp = pending_notes))
    {
      free (temp->marker);
      free (temp->note);
      pending_notes = pending_notes->next;
      free (temp);
    }
  first_footnote_this_node = 1;
  footnote_count = 0;
  current_footnote_number = 1;     /* for html */
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 288 of file footnote.c.

{
  FN *footnote = pending_notes;

  if (!pending_notes)
    return;

  if (html)
    {
      add_html_block_elt ("<div class=\"footnote\">\n<hr>\n");
      /* We add an anchor here so @printindex can refer to this point
         (as the node name) for entries defined in footnotes.  */
      if (!splitting)
        add_word ("<a name=\"texinfo-footnotes-in-document\"></a>");
      add_word_args ("<h4>%s</h4>", (char *) _("Footnotes"));
    }
  else
    switch (footnote_style)
      {
      case separate_node:
        {
          char *old_current_node = current_node;
          char *old_command = xstrdup (command);

          already_outputting_pending_notes++;
          execute_string ("%cnode %s-Footnotes,,,%s\n",
                          COMMAND_PREFIX, current_node, current_node);
          already_outputting_pending_notes--;
          current_node = old_current_node;
          free (command);
          command = old_command;
        }
      break;

      case end_node:
        close_paragraph ();
        in_fixed_width_font++;
        /* This string should be translated according to the
           @documentlanguage, not the current LANG.  We can't do that
           yet, so leave it in English.  */
        execute_string ("---------- Footnotes ----------\n\n");
        in_fixed_width_font--;
        break;
      }

  /* Handle the footnotes in reverse order. */
  {
    int save_in_fixed_width_font = in_fixed_width_font;
    FN **array = xmalloc ((footnote_count + 1) * sizeof (FN *));
    array[footnote_count] = NULL;

    while (--footnote_count > -1)
      {
        array[footnote_count] = footnote;
        footnote = footnote->next;
      }

    filling_enabled = 1;
    indented_fill = 1;
    in_fixed_width_font = 0;

    while ((footnote = array[++footnote_count]))
      {
        if (html)
          {
           /* Make the text of every footnote begin a separate paragraph.  */
            add_html_block_elt ("<p class=\"footnote\"><small>");
            /* Make footnote number a link to its definition.  */
            add_word_args ("[<a name=\"fn-%d\" href=\"#fnd-%d\">%d</a>]",
                        footnote->number, footnote->number, footnote->number);
            add_word ("</small> ");
            already_outputting_pending_notes++;
            execute_string ("%s", footnote->note);
            already_outputting_pending_notes--;
            add_word ("</p>\n");
          }
        else
          {
            char *old_current_node = current_node;
            char *old_command = xstrdup (command);

            already_outputting_pending_notes++;
            execute_string ("%canchor{%s-Footnote-%d}(%s) %s",
                            COMMAND_PREFIX, current_node, footnote->number,
                            footnote->marker, footnote->note);
            already_outputting_pending_notes--;
            current_node = old_current_node;
            free (command);
            command = old_command;
          }

        close_paragraph ();
      }

    if (html)
      add_word ("<hr></div>");
    close_paragraph ();
    free (array);

    in_fixed_width_font = save_in_fixed_width_font;
  }

  free_pending_notes ();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void remember_note ( char *  marker,
char *  note 
) [static]

Definition at line 100 of file footnote.c.

{
  FN *temp = xmalloc (sizeof (FN));

  temp->marker = xstrdup (marker);
  temp->note = xstrdup (note);
  temp->next = pending_notes;
  temp->number = current_footnote_number;
  pending_notes = temp;
  footnote_count++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int set_footnote_style ( char *  string)

Definition at line 61 of file footnote.c.

{
  if (strcasecmp (string, "separate") == 0)
    footnote_style = separate_node;
  else if (strcasecmp (string, "end") == 0)
    footnote_style = end_node;
  else
    return -1;

 return 0;
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 40 of file footnote.c.

Definition at line 34 of file footnote.c.

Definition at line 56 of file footnote.c.

Definition at line 57 of file footnote.c.

Definition at line 55 of file footnote.c.

Definition at line 30 of file footnote.c.

Definition at line 37 of file footnote.c.

Definition at line 95 of file footnote.c.