bookloupe/counters.c
changeset 176 302b4681a857
parent 103 adc06e9e8470
     1.1 --- a/bookloupe/counters.c	Mon Sep 23 21:18:27 2013 +0100
     1.2 +++ b/bookloupe/counters.c	Sun Sep 29 09:18:05 2013 +0100
     1.3 @@ -8,6 +8,14 @@
     1.4      int open,close;
     1.5  };
     1.6  
     1.7 +GQuark counters_error_quark(void)
     1.8 +{
     1.9 +    static GQuark quark;
    1.10 +    if (!quark)
    1.11 +	quark=g_quark_from_static_string("counters_error");
    1.12 +    return quark;
    1.13 +}
    1.14 +
    1.15  static struct matching_counter *matching_counter_new(void)
    1.16  {
    1.17      return g_slice_new0(struct matching_counter);
    1.18 @@ -45,11 +53,64 @@
    1.19  	return GINT_TO_POINTER((gint)CHAR_SQUOTE);
    1.20      else if (ch==CHAR_LS_QUOTE || ch==CHAR_RS_QUOTE)
    1.21  	return GINT_TO_POINTER((gint)CHAR_LS_QUOTE);
    1.22 +    else if (ch==CHAR_LD_QUOTE || ch==CHAR_RD_QUOTE)
    1.23 +	return GINT_TO_POINTER((gint)CHAR_LD_QUOTE);
    1.24 +    else if (ch==CHAR_DQUOTE)
    1.25 +	return GINT_TO_POINTER((gint)ch);
    1.26      else if (ch<0x4000 || ch-0x4000>=NO_SPECIAL_COUNTERS)
    1.27 +	g_warning("Matching pair not found for U+%04" G_GINT32_MODIFIER "X",ch);
    1.28 +    return GINT_TO_POINTER((gint)ch);
    1.29 +}
    1.30 +
    1.31 +gboolean innermost_quote_matches(struct counters *counters,gunichar ch)
    1.32 +{
    1.33 +    gpointer head;
    1.34 +    if (counters->open_quotes)
    1.35 +	head=counters->open_quotes->data;
    1.36 +    else
    1.37 +	head=NULL;
    1.38 +    return head==matching_key(ch);
    1.39 +}
    1.40 +
    1.41 +gboolean count_quote(struct counters *counters,gunichar ch,QuoteClass klass,
    1.42 +  GError **err)
    1.43 +{
    1.44 +    gboolean retval=TRUE;
    1.45 +    gpointer head;
    1.46 +    if (counters->open_quotes)
    1.47 +	head=counters->open_quotes->data;
    1.48 +    else
    1.49 +	head=NULL;
    1.50 +    switch(klass)
    1.51      {
    1.52 -	g_warning("Matching pair not found for U+%04" G_GINT32_MODIFIER "X",ch);
    1.53 -	return GINT_TO_POINTER((gint)ch);
    1.54 +	case NEUTRAL_QUOTE:
    1.55 +	    if (head!=matching_key(ch))
    1.56 +		goto opening;
    1.57 +	    /* else fall through */
    1.58 +	case CLOSING_QUOTE:
    1.59 +	    if (head!=matching_key(ch))
    1.60 +	    {
    1.61 +		g_set_error(err,COUNTERS_ERROR,COUNTERS_ERROR_FAILED,
    1.62 +		  "Closing quotation mark with no matching open?");
    1.63 +		retval=FALSE;
    1.64 +	    }
    1.65 +	    else
    1.66 +		counters->open_quotes=g_slist_delete_link(counters->open_quotes,
    1.67 +		  counters->open_quotes);
    1.68 +	    break;
    1.69 +	case OPENING_QUOTE:
    1.70 +	    if (head==matching_key(ch))
    1.71 +	    {
    1.72 +		g_set_error(err,COUNTERS_ERROR,COUNTERS_ERROR_FAILED,
    1.73 +		  "Directly nested quotation marks of same type?");
    1.74 +		retval=FALSE;
    1.75 +	    }
    1.76 +opening:
    1.77 +	    head=matching_key(ch);
    1.78 +	    counters->open_quotes=g_slist_prepend(counters->open_quotes,head);
    1.79 +	    break;
    1.80      }
    1.81 +    return retval;
    1.82  }
    1.83  
    1.84  void increment_matching(struct counters *counters,gunichar ch,gboolean open)