Пример #1
0
BibtexField * 
bibtex_reverse_field (BibtexField * field,
		      gboolean use_braces,
		      gboolean do_quote) {
    BibtexStruct * s = NULL;
    gchar * string, * tmp;
    gboolean is_upper, has_space, is_command, was_command;
    gint i;
    BibtexAuthor * author;

    static GString *      st      = NULL;
    static RECODE_OUTER   outer   = NULL;
    static RECODE_REQUEST request = NULL;

    g_return_val_if_fail (field != NULL, NULL);

    if (st == NULL) st = g_string_sized_new (16);
	
    if (outer == NULL) {
	outer = recode_new_outer (false);
	g_assert (outer != NULL);
    }

    if (request == NULL) {
	request = recode_new_request (outer);
	g_assert (request != NULL);
	if (! recode_scan_request (request, "latin1..latex")) {
	    g_error ("can't create recoder");
	}
    }

    if (field->structure) {
	bibtex_struct_destroy (field->structure, TRUE);
	field->structure = NULL;
    }

    field->loss = FALSE;

    switch (field->type) {
    case BIBTEX_OTHER:
    case BIBTEX_VERBATIM:
	g_return_val_if_fail (field->text != NULL, NULL);

	g_string_truncate (st, 0);

	if (! use_braces) {
	    if (strchr (field->text, '"')) {
	        use_braces = TRUE;
	    }
	}

	if (use_braces) {
	    g_string_append (st, "@preamble{{");
	}
	else {
	    g_string_append (st, "@preamble{\"");
	}

	if (do_quote) {
	  tmp = recode_string (request, field->text);
	  g_string_append (st, tmp);
	  g_free (tmp);
	}
	else {
	  g_string_append (st, field->text);
	}

	if (use_braces) {
	    g_string_append (st, "}}");
	}
	else {
	    g_string_append (st, "\"}");
	}

	s = text_to_struct (st->str);
	break;

    case BIBTEX_TITLE:
	g_return_val_if_fail (field->text != NULL, NULL);

	g_string_truncate (st, 0);
	
	if (! use_braces) {
	    if (strchr (field->text, '"')) {
	        use_braces = TRUE;
	    }
	}

	tmp = recode_string (request, field->text);

	if (use_braces) {
	    g_string_append (st, "@preamble{{");
	}
	else {
	    g_string_append (st, "@preamble{\"");
	}

	/* Put the first lower case between {} */
	string = tmp;
	if (* tmp >= 'a' && * tmp <= 'z') {
	    /* Put the beginning in lower cases */
	    g_string_append_c (st, '{');
	    g_string_append_c (st, * tmp);
	    g_string_append_c (st, '}');
	}
	else {
	    /* The first character is done */
	    g_string_append_c (st, * tmp);
	}
	
	tmp ++;

	/* check for upper cases afterward */
	is_upper    = false;
	is_command  = false;
	was_command = false;

	while (* tmp) {
	    /* start a latex command */
	    if (* tmp == '\\') {

		/* eventually closes the bracket */
		if (is_upper) {
		    is_upper = false;
		    g_string_append_c (st, '}');
		}

		is_command  = true;
		was_command = false;
		g_string_append_c (st, * tmp);
		tmp ++;

		continue;
	    }
	    if (is_command) {
		if (! ((* tmp >= 'a' && * tmp <= 'z') ||
		       (* tmp >= 'A' && * tmp <= 'Z'))) {
		    is_command  = false;
		    was_command = true;
		}
		g_string_append_c (st, * tmp);
		tmp ++;

		continue;
	    }

	    if (* tmp >= 'A' && * tmp <= 'Z') {
		if (! is_upper) {
		    g_string_append_c (st, '{');
		    g_string_append_c (st, * tmp);
		    if (was_command) {
			g_string_append_c (st, '}');
		    } else {
			is_upper = true;
		    }
		} else {
		    g_string_append_c (st, * tmp);
		}
	    }
	    else {
		if (is_upper) {
		    g_string_append_c (st, '}');
		    is_upper = false;
		}

		g_string_append_c (st, * tmp);
	    }
	    was_command = false;
	    tmp ++;
	}

	/* eventually close the brackets */
	if (is_upper) {
	    g_string_append_c (st, '}');
	    is_upper = false;
	}
	g_free (string);

	if (use_braces) {
	    g_string_append (st, "}}");
	}
	else {
	    g_string_append (st, "\"}");
	}

	s = text_to_struct (st->str);
	break;

    case BIBTEX_AUTHOR:
	g_return_val_if_fail (field->field.author != NULL, NULL);

	g_string_truncate (st, 0);

	/* Create a simple preamble to parse */
	if (! use_braces) {
	    for (i = 0 ; i < field->field.author->len; i ++) {
		author = & g_array_index (field->field.author, BibtexAuthor, i);
		
		if (author->last && strchr (author->last, '"')) {
		    use_braces = TRUE;
		    break;
		}
		if (author->lineage && strchr (author->lineage, '"')) {
		    use_braces = TRUE;
		    break;
		}
		if (author->first && strchr (author->first, '"')) {
		    use_braces = TRUE;
		    break;
		}
	    }
	}
	
	if (use_braces) {
	    g_string_append (st, "@preamble{{");
	}
	else {
	    g_string_append (st, "@preamble{\"");
	}

	for (i = 0 ; i < field->field.author->len; i ++) {
	    author = & g_array_index (field->field.author, BibtexAuthor, i);

	    if (i != 0) {
		g_string_append (st, " and ");
	    }

	    if (author->last) {
	        /* quotes if there is no first name */
	        has_space = author_needs_quotes (author->last) ||
		  (author->first == NULL && 
		   strpbrk (author->last, " \t") != NULL);

		if (has_space) {
		    g_string_append_c (st, '{');
		}

		tmp = recode_string (request, author->last);
		g_string_append (st, tmp);
		g_free (tmp);

		if (has_space) {
		    g_string_append_c (st, '}');
		}
	    }

	    if (author->lineage) {
		g_string_append (st, ", ");

	        has_space = author_needs_quotes (author->lineage);

		if (has_space) {
		    g_string_append_c (st, '{');
		}

		tmp = recode_string (request, author->lineage);
		g_string_append (st, tmp);
		g_free (tmp);

		if (has_space) {
		    g_string_append_c (st, '}');
		}
	    }


	    if (author->first) {
		g_string_append (st, ", ");

	        has_space = author_needs_quotes (author->first);

		if (has_space) {
		    g_string_append_c (st, '{');
		}

		tmp = recode_string (request, author->first);
		g_string_append (st, tmp);
		g_free (tmp);

		if (has_space) {
		    g_string_append_c (st, '}');
		}
	    }
	}

	if (use_braces) {
	    g_string_append (st, "}}");
	}
	else {
	    g_string_append (st, "\"}");
	}

	s = text_to_struct (st->str);
	break;

    case BIBTEX_DATE:
	s = bibtex_struct_new (BIBTEX_STRUCT_TEXT);
	s->value.text = g_strdup_printf ("%d", field->field.date.year);
	break;

    default:
	g_assert_not_reached ();
    }

    field->structure = s;

    /* remove text field */
    if (field->text) {
	g_free (field->text);

	field->text = NULL;
	field->converted = FALSE;
    }

    return field;
}
Пример #2
0
/* caching request creator
   returns recode request either found in cache or, if not found, a newly
   created (and immediately put into the cache)
   returns NULL on failure */
static RECODE_REQUEST
get_recode_request(const char *encreq)
{
  static RecRequest *request_cache = NULL; /* recode request cache */

  RECODE_REQUEST request;
  RecRequest *req;

  /* try to find the request in cache (bubble sorting it meanwhile) */
  for (req = request_cache; req != NULL; req = req->next) {
    if (strcmp(req->request_string, encreq) == 0)
      break;

    if (req->next != NULL && req->count < req->next->count) {
      RecRequest tmpreq;
      /* it's easier to exchange contents instead of pointers here */
      tmpreq.request = req->request;
      tmpreq.count = req->count;
      tmpreq.request_string = req->request_string;

      req->request = req->next->request;
      req->count = req->next->count;
      req->request_string = req->next->request_string;

      req->next->request = tmpreq.request;
      req->next->count = tmpreq.count;
      req->next->request_string = tmpreq.request_string;
    }
  }
  /* found, increment usage count and return it */
  if (req != NULL) {
    req->count++;
    return req->request;
  }
  /* request not found, ask for a new one */
  if ((request = recode_new_request(outer)) == NULL) {
    fprintf(stderr, "%s: recode library doesn't accept new requests\n",
            program_name);
    return NULL; /* maybe we could simply abort */
  }
  /* Set some options. */
  request->diacritics_only = request->ascii_graphics = true;
  /* create request from request string */
  if (!recode_scan_request(request, encreq)) {
    if (options.verbosity_level) {
      fprintf(stderr, "%s: errorneous recoding request `%s'\n",
                     program_name,encreq);
    }
    recode_delete_request(request);
    return NULL;
  }
  /* add it to end of cache */
  if ((req = request_cache) != NULL) {
    while (req->next != NULL) req = req->next;
    req->next = NEW(RecRequest, 1);
    req = req->next;
  }
  else {
    req = NEW(RecRequest, 1);
    request_cache = req;
  }
  req->request = request;
  req->request_string = enca_strdup(encreq);
  req->count = 1;
  req->next = NULL;

  return request;
}