1.1 --- a/bookloupe/bookloupe.c Sun May 26 16:54:06 2013 +0100
1.2 +++ b/bookloupe/bookloupe.c Sun May 26 17:23:48 2013 +0100
1.3 @@ -1781,6 +1781,252 @@
1.4 }
1.5 }
1.6
1.7 +struct parities {
1.8 + int dquote,squote;
1.9 +};
1.10 +
1.11 +/*
1.12 + * check_for_misspaced_punctuation:
1.13 + *
1.14 + * Look for added or missing spaces around punctuation and quotes.
1.15 + * If there is a punctuation character like ! with no space on
1.16 + * either side, suspect a missing!space. If there are spaces on
1.17 + * both sides , assume a typo. If we see a double quote with no
1.18 + * space or punctuation on either side of it, assume unspaced
1.19 + * quotes "like"this.
1.20 + */
1.21 +void check_for_misspaced_punctuation(const char *aline,
1.22 + struct parities *parities,int isemptyline)
1.23 +{
1.24 + int i,llen,isacro,isellipsis;
1.25 + const char *s;
1.26 + llen=strlen(aline);
1.27 + for (i=1;i<llen;i++)
1.28 + {
1.29 + /* For each character in the line after the first. */
1.30 + if (strchr(".?!,;:_",aline[i])) /* if it's punctuation */
1.31 + {
1.32 + /* we need to suppress warnings for acronyms like M.D. */
1.33 + isacro=0;
1.34 + /* we need to suppress warnings for ellipsis . . . */
1.35 + isellipsis=0;
1.36 + /* if there are letters on both sides of it or ... */
1.37 + if (gcisalpha(aline[i-1]) && gcisalpha(aline[i+1]) ||
1.38 + gcisalpha(aline[i+1]) && strchr("?!,;:",aline[i]))
1.39 + {
1.40 + /* ...if it's strict punctuation followed by an alpha */
1.41 + if (aline[i]=='.')
1.42 + {
1.43 + if (i>2 && aline[i-2]=='.')
1.44 + isacro=1;
1.45 + if (i+2<llen && aline[i+2]=='.')
1.46 + isacro=1;
1.47 + }
1.48 + if (!isacro)
1.49 + {
1.50 + if (pswit[ECHO_SWITCH])
1.51 + printf("\n%s\n",aline);
1.52 + if (!pswit[OVERVIEW_SWITCH])
1.53 + printf(" Line %ld column %d - Missing space?\n",
1.54 + linecnt,i+1);
1.55 + else
1.56 + cnt_punct++;
1.57 + }
1.58 + }
1.59 + if (aline[i-1]==CHAR_SPACE &&
1.60 + (aline[i+1]==CHAR_SPACE || aline[i+1]==0))
1.61 + {
1.62 + /*
1.63 + * If there are spaces on both sides,
1.64 + * or space before and end of line.
1.65 + */
1.66 + if (aline[i]=='.')
1.67 + {
1.68 + if (i>2 && aline[i-2]=='.')
1.69 + isellipsis=1;
1.70 + if (i+2<llen && aline[i+2]=='.')
1.71 + isellipsis=1;
1.72 + }
1.73 + if (!isemptyline && !isellipsis)
1.74 + {
1.75 + if (pswit[ECHO_SWITCH])
1.76 + printf("\n%s\n",aline);
1.77 + if (!pswit[OVERVIEW_SWITCH])
1.78 + printf(" Line %ld column %d - "
1.79 + "Spaced punctuation?\n",linecnt,i+1);
1.80 + else
1.81 + cnt_punct++;
1.82 + }
1.83 + }
1.84 + }
1.85 + }
1.86 + /* Split out the characters that CANNOT be preceded by space. */
1.87 + llen=strlen(aline);
1.88 + for (i=1;i<llen;i++)
1.89 + {
1.90 + /* for each character in the line after the first */
1.91 + if (strchr("?!,;:",aline[i]))
1.92 + {
1.93 + /* if it's punctuation that _cannot_ have a space before it */
1.94 + if (aline[i-1]==CHAR_SPACE && !isemptyline &&
1.95 + aline[i+1]!=CHAR_SPACE)
1.96 + {
1.97 + /*
1.98 + * If aline[i+1) DOES == space,
1.99 + * it was already reported just above.
1.100 + */
1.101 + if (pswit[ECHO_SWITCH])
1.102 + printf("\n%s\n",aline);
1.103 + if (!pswit[OVERVIEW_SWITCH])
1.104 + printf(" Line %ld column %d - Spaced punctuation?\n",
1.105 + linecnt,i+1);
1.106 + else
1.107 + cnt_punct++;
1.108 + }
1.109 + }
1.110 + }
1.111 + /*
1.112 + * Special case " .X" where X is any alpha.
1.113 + * This plugs a hole in the acronym code above.
1.114 + * Inelegant, but maintainable.
1.115 + */
1.116 + llen=strlen(aline);
1.117 + for (i=1;i<llen;i++)
1.118 + {
1.119 + /* for each character in the line after the first */
1.120 + if (aline[i]=='.')
1.121 + {
1.122 + /* if it's a period */
1.123 + if (aline[i-1]==CHAR_SPACE && gcisalpha(aline[i+1]))
1.124 + {
1.125 + /*
1.126 + * If the period follows a space and
1.127 + * is followed by a letter.
1.128 + */
1.129 + if (pswit[ECHO_SWITCH])
1.130 + printf("\n%s\n",aline);
1.131 + if (!pswit[OVERVIEW_SWITCH])
1.132 + printf(" Line %ld column %d - Spaced punctuation?\n",
1.133 + linecnt,i+1);
1.134 + else
1.135 + cnt_punct++;
1.136 + }
1.137 + }
1.138 + }
1.139 + for (i=1;i<llen;i++)
1.140 + {
1.141 + /* for each character in the line after the first */
1.142 + if (aline[i]==CHAR_DQUOTE)
1.143 + {
1.144 + if (!strchr(" _-.'`,;:!/([{?}])",aline[i-1]) &&
1.145 + !strchr(" _-.'`,;:!/([{?}])",aline[i+1]) && aline[i+1] ||
1.146 + !strchr(" _-([{'`",aline[i-1]) && gcisalpha(aline[i+1]))
1.147 + {
1.148 + if (pswit[ECHO_SWITCH])
1.149 + printf("\n%s\n",aline);
1.150 + if (!pswit[OVERVIEW_SWITCH])
1.151 + printf(" Line %ld column %d - Unspaced quotes?\n",
1.152 + linecnt,i+1);
1.153 + else
1.154 + cnt_punct++;
1.155 + }
1.156 + }
1.157 + }
1.158 + /* Check parity of quotes. */
1.159 + for (s=aline;*s;s++)
1.160 + {
1.161 + if (*s==CHAR_DQUOTE)
1.162 + {
1.163 + parities->dquote=!parities->dquote;
1.164 + if (!parities->dquote)
1.165 + {
1.166 + /* parity even */
1.167 + if (!strchr("_-.'`/,;:!?)]} ",s[1]))
1.168 + {
1.169 + if (pswit[ECHO_SWITCH])
1.170 + printf("\n%s\n",aline);
1.171 + if (!pswit[OVERVIEW_SWITCH])
1.172 + printf(" Line %ld column %d - "
1.173 + "Wrongspaced quotes?\n",linecnt,(int)(s-aline)+1);
1.174 + else
1.175 + cnt_punct++;
1.176 + }
1.177 + }
1.178 + else
1.179 + {
1.180 + /* parity odd */
1.181 + if (!gcisalpha(s[1]) && !isdigit(s[1]) &&
1.182 + !strchr("_-/.'`([{$",s[1]) || !s[1])
1.183 + {
1.184 + if (pswit[ECHO_SWITCH])
1.185 + printf("\n%s\n",aline);
1.186 + if (!pswit[OVERVIEW_SWITCH])
1.187 + printf(" Line %ld column %d - "
1.188 + "Wrongspaced quotes?\n",linecnt,(int)(s-aline)+1);
1.189 + else
1.190 + cnt_punct++;
1.191 + }
1.192 + }
1.193 + }
1.194 + }
1.195 + if (*aline==CHAR_DQUOTE)
1.196 + {
1.197 + if (strchr(",;:!?)]} ",aline[1]))
1.198 + {
1.199 + if (pswit[ECHO_SWITCH])
1.200 + printf("\n%s\n",aline);
1.201 + if (!pswit[OVERVIEW_SWITCH])
1.202 + printf(" Line %ld column 1 - Wrongspaced quotes?\n",
1.203 + linecnt);
1.204 + else
1.205 + cnt_punct++;
1.206 + }
1.207 + }
1.208 + if (pswit[SQUOTE_SWITCH])
1.209 + {
1.210 + for (s=aline;*s;s++)
1.211 + {
1.212 + if ((*s==CHAR_SQUOTE || *s==CHAR_OPEN_SQUOTE) &&
1.213 + (s==aline || s>aline && !gcisalpha(s[-1]) ||
1.214 + !gcisalpha(s[1])))
1.215 + {
1.216 + parities->squote=!parities->squote;
1.217 + if (!parities->squote)
1.218 + {
1.219 + /* parity even */
1.220 + if (!strchr("_-.'`/\",;:!?)]} ",s[1]))
1.221 + {
1.222 + if (pswit[ECHO_SWITCH])
1.223 + printf("\n%s\n",aline);
1.224 + if (!pswit[OVERVIEW_SWITCH])
1.225 + printf(" Line %ld column %d - "
1.226 + "Wrongspaced singlequotes?\n",
1.227 + linecnt,(int)(s-aline)+1);
1.228 + else
1.229 + cnt_punct++;
1.230 + }
1.231 + }
1.232 + else
1.233 + {
1.234 + /* parity odd */
1.235 + if (!gcisalpha(s[1]) && !isdigit(s[1]) &&
1.236 + !strchr("_-/\".'`",s[1]) || !s[1])
1.237 + {
1.238 + if (pswit[ECHO_SWITCH])
1.239 + printf("\n%s\n",aline);
1.240 + if (!pswit[OVERVIEW_SWITCH])
1.241 + printf(" Line %ld column %d - "
1.242 + "Wrongspaced singlequotes?\n",
1.243 + linecnt,(int)(s-aline)+1);
1.244 + else
1.245 + cnt_punct++;
1.246 + }
1.247 + }
1.248 + }
1.249 + }
1.250 + }
1.251 +}
1.252 +
1.253 /*
1.254 * procfile:
1.255 *
1.256 @@ -1795,10 +2041,10 @@
1.257 struct warnings *warnings;
1.258 struct counters counters={0};
1.259 struct line_properties last={0};
1.260 + struct parities parities={0};
1.261 int isemptyline;
1.262 long squot,start_para_line;
1.263 signed int i,llen,isacro,isellipsis;
1.264 - signed int dquotepar,squotepar;
1.265 signed int isnewpara;
1.266 char dquote_err[80],squote_err[80],rbrack_err[80],sbrack_err[80],
1.267 cbrack_err[80],unders_err[80];
1.268 @@ -1810,7 +2056,6 @@
1.269 squot=0;
1.270 i=llen=isacro=isellipsis=0;
1.271 isnewpara=enddash=0;
1.272 - dquotepar=squotepar=0;
1.273 infile=fopen(filename,"rb");
1.274 if (!infile)
1.275 {
1.276 @@ -1946,7 +2191,7 @@
1.277 /* Capture its first line in case we want to report it later. */
1.278 strncpy(parastart,aline,80);
1.279 parastart[79]=0;
1.280 - dquotepar=squotepar=0; /* restart the quote count */
1.281 + memset(&parities,0,sizeof(parities)); /* restart the quote count */
1.282 s=aline;
1.283 while (!gcisalpha(*s) && !gcisdigit(*s) && *s)
1.284 s++;
1.285 @@ -2022,237 +2267,7 @@
1.286 check_for_extra_period(aline,warnings);
1.287 check_for_following_punctuation(aline);
1.288 check_for_typos(aline,warnings);
1.289 - /*
1.290 - * Look for added or missing spaces around punctuation and quotes.
1.291 - * If there is a punctuation character like ! with no space on
1.292 - * either side, suspect a missing!space. If there are spaces on
1.293 - * both sides , assume a typo. If we see a double quote with no
1.294 - * space or punctuation on either side of it, assume unspaced
1.295 - * quotes "like"this.
1.296 - */
1.297 - llen=strlen(aline);
1.298 - for (i=1;i<llen;i++)
1.299 - {
1.300 - /* For each character in the line after the first. */
1.301 - if (strchr(".?!,;:_",aline[i])) /* if it's punctuation */
1.302 - {
1.303 - /* we need to suppress warnings for acronyms like M.D. */
1.304 - isacro=0;
1.305 - /* we need to suppress warnings for ellipsis . . . */
1.306 - isellipsis=0;
1.307 - /* if there are letters on both sides of it or ... */
1.308 - if (gcisalpha(aline[i-1]) && gcisalpha(aline[i+1]) ||
1.309 - gcisalpha(aline[i+1]) && strchr("?!,;:",aline[i]))
1.310 - {
1.311 - /* ...if it's strict punctuation followed by an alpha */
1.312 - if (aline[i]=='.')
1.313 - {
1.314 - if (i>2 && aline[i-2]=='.')
1.315 - isacro=1;
1.316 - if (i+2<llen && aline[i+2]=='.')
1.317 - isacro=1;
1.318 - }
1.319 - if (!isacro)
1.320 - {
1.321 - if (pswit[ECHO_SWITCH])
1.322 - printf("\n%s\n",aline);
1.323 - if (!pswit[OVERVIEW_SWITCH])
1.324 - printf(" Line %ld column %d - Missing space?\n",
1.325 - linecnt,i+1);
1.326 - else
1.327 - cnt_punct++;
1.328 - }
1.329 - }
1.330 - if (aline[i-1]==CHAR_SPACE &&
1.331 - (aline[i+1]==CHAR_SPACE || aline[i+1]==0))
1.332 - {
1.333 - /*
1.334 - * If there are spaces on both sides,
1.335 - * or space before and end of line.
1.336 - */
1.337 - if (aline[i]=='.')
1.338 - {
1.339 - if (i>2 && aline[i-2]=='.')
1.340 - isellipsis=1;
1.341 - if (i+2<llen && aline[i+2]=='.')
1.342 - isellipsis=1;
1.343 - }
1.344 - if (!isemptyline && !isellipsis)
1.345 - {
1.346 - if (pswit[ECHO_SWITCH])
1.347 - printf("\n%s\n",aline);
1.348 - if (!pswit[OVERVIEW_SWITCH])
1.349 - printf(" Line %ld column %d - "
1.350 - "Spaced punctuation?\n",linecnt,i+1);
1.351 - else
1.352 - cnt_punct++;
1.353 - }
1.354 - }
1.355 - }
1.356 - }
1.357 - /* Split out the characters that CANNOT be preceded by space. */
1.358 - llen=strlen(aline);
1.359 - for (i=1;i<llen;i++)
1.360 - {
1.361 - /* for each character in the line after the first */
1.362 - if (strchr("?!,;:",aline[i]))
1.363 - {
1.364 - /* if it's punctuation that _cannot_ have a space before it */
1.365 - if (aline[i-1]==CHAR_SPACE && !isemptyline &&
1.366 - aline[i+1]!=CHAR_SPACE)
1.367 - {
1.368 - /*
1.369 - * If aline[i+1) DOES == space,
1.370 - * it was already reported just above.
1.371 - */
1.372 - if (pswit[ECHO_SWITCH])
1.373 - printf("\n%s\n",aline);
1.374 - if (!pswit[OVERVIEW_SWITCH])
1.375 - printf(" Line %ld column %d - Spaced punctuation?\n",
1.376 - linecnt,i+1);
1.377 - else
1.378 - cnt_punct++;
1.379 - }
1.380 - }
1.381 - }
1.382 - /*
1.383 - * Special case " .X" where X is any alpha.
1.384 - * This plugs a hole in the acronym code above.
1.385 - * Inelegant, but maintainable.
1.386 - */
1.387 - llen=strlen(aline);
1.388 - for (i=1;i<llen;i++)
1.389 - {
1.390 - /* for each character in the line after the first */
1.391 - if (aline[i]=='.')
1.392 - {
1.393 - /* if it's a period */
1.394 - if (aline[i-1]==CHAR_SPACE && gcisalpha(aline[i+1]))
1.395 - {
1.396 - /*
1.397 - * If the period follows a space and
1.398 - * is followed by a letter.
1.399 - */
1.400 - if (pswit[ECHO_SWITCH])
1.401 - printf("\n%s\n",aline);
1.402 - if (!pswit[OVERVIEW_SWITCH])
1.403 - printf(" Line %ld column %d - Spaced punctuation?\n",
1.404 - linecnt,i+1);
1.405 - else
1.406 - cnt_punct++;
1.407 - }
1.408 - }
1.409 - }
1.410 - for (i=1;i<llen;i++)
1.411 - {
1.412 - /* for each character in the line after the first */
1.413 - if (aline[i]==CHAR_DQUOTE)
1.414 - {
1.415 - if (!strchr(" _-.'`,;:!/([{?}])",aline[i-1]) &&
1.416 - !strchr(" _-.'`,;:!/([{?}])",aline[i+1]) && aline[i+1] ||
1.417 - !strchr(" _-([{'`",aline[i-1]) && gcisalpha(aline[i+1]))
1.418 - {
1.419 - if (pswit[ECHO_SWITCH])
1.420 - printf("\n%s\n",aline);
1.421 - if (!pswit[OVERVIEW_SWITCH])
1.422 - printf(" Line %ld column %d - Unspaced quotes?\n",
1.423 - linecnt,i+1);
1.424 - else
1.425 - cnt_punct++;
1.426 - }
1.427 - }
1.428 - }
1.429 - /* Check parity of quotes. */
1.430 - for (s=aline;*s;s++)
1.431 - {
1.432 - if (*s==CHAR_DQUOTE)
1.433 - {
1.434 - if (!(dquotepar=!dquotepar))
1.435 - {
1.436 - /* parity even */
1.437 - if (!strchr("_-.'`/,;:!?)]} ",s[1]))
1.438 - {
1.439 - if (pswit[ECHO_SWITCH])
1.440 - printf("\n%s\n",aline);
1.441 - if (!pswit[OVERVIEW_SWITCH])
1.442 - printf(" Line %ld column %d - "
1.443 - "Wrongspaced quotes?\n",linecnt,(int)(s-aline)+1);
1.444 - else
1.445 - cnt_punct++;
1.446 - }
1.447 - }
1.448 - else
1.449 - {
1.450 - /* parity odd */
1.451 - if (!gcisalpha(s[1]) && !isdigit(s[1]) &&
1.452 - !strchr("_-/.'`([{$",s[1]) || !s[1])
1.453 - {
1.454 - if (pswit[ECHO_SWITCH])
1.455 - printf("\n%s\n",aline);
1.456 - if (!pswit[OVERVIEW_SWITCH])
1.457 - printf(" Line %ld column %d - "
1.458 - "Wrongspaced quotes?\n",linecnt,(int)(s-aline)+1);
1.459 - else
1.460 - cnt_punct++;
1.461 - }
1.462 - }
1.463 - }
1.464 - }
1.465 - if (*aline==CHAR_DQUOTE)
1.466 - {
1.467 - if (strchr(",;:!?)]} ",aline[1]))
1.468 - {
1.469 - if (pswit[ECHO_SWITCH])
1.470 - printf("\n%s\n",aline);
1.471 - if (!pswit[OVERVIEW_SWITCH])
1.472 - printf(" Line %ld column 1 - Wrongspaced quotes?\n",
1.473 - linecnt);
1.474 - else
1.475 - cnt_punct++;
1.476 - }
1.477 - }
1.478 - if (pswit[SQUOTE_SWITCH])
1.479 - {
1.480 - for (s=aline;*s;s++)
1.481 - {
1.482 - if ((*s==CHAR_SQUOTE || *s==CHAR_OPEN_SQUOTE) &&
1.483 - (s==aline || s>aline && !gcisalpha(s[-1]) ||
1.484 - !gcisalpha(s[1])))
1.485 - {
1.486 - if (!(squotepar=!squotepar))
1.487 - {
1.488 - /* parity even */
1.489 - if (!strchr("_-.'`/\",;:!?)]} ",s[1]))
1.490 - {
1.491 - if (pswit[ECHO_SWITCH])
1.492 - printf("\n%s\n",aline);
1.493 - if (!pswit[OVERVIEW_SWITCH])
1.494 - printf(" Line %ld column %d - "
1.495 - "Wrongspaced singlequotes?\n",
1.496 - linecnt,(int)(s-aline)+1);
1.497 - else
1.498 - cnt_punct++;
1.499 - }
1.500 - }
1.501 - else
1.502 - {
1.503 - /* parity odd */
1.504 - if (!gcisalpha(s[1]) && !isdigit(s[1]) &&
1.505 - !strchr("_-/\".'`",s[1]) || !s[1])
1.506 - {
1.507 - if (pswit[ECHO_SWITCH])
1.508 - printf("\n%s\n",aline);
1.509 - if (!pswit[OVERVIEW_SWITCH])
1.510 - printf(" Line %ld column %d - "
1.511 - "Wrongspaced singlequotes?\n",
1.512 - linecnt,(int)(s-aline)+1);
1.513 - else
1.514 - cnt_punct++;
1.515 - }
1.516 - }
1.517 - }
1.518 - }
1.519 - }
1.520 + check_for_misspaced_punctuation(aline,&parities,isemptyline);
1.521 /*
1.522 * Look for double punctuation like ,. or ,,
1.523 * Thanks to DW for the suggestion!