#include #include #include #include gchar *plain_text(const char *text) { const char *s; GString *plain=g_string_new(NULL); while(*text) { if (*text=='<') { s=strchr(text+1,'>'); if (s) { text=s+1; continue; } } else if (g_str_has_prefix(text,"[**")) { s=strchr(text+3,']'); if (s) { text=s+1; continue; } } else if (g_str_has_prefix(text,"\n/#\n")) text+=3; else if (g_str_has_prefix(text,"\n/*\n")) text+=3; else if (g_str_has_prefix(text,"\n#/\n")) text+=3; else if (g_str_has_prefix(text,"\n*/\n")) text+=3; g_string_append_c(plain,*text++); } return g_string_free(plain,FALSE); } main(int argc,char **argv) { gchar *contents,*s; gchar **paras; gsize len; int i,j,cnt_s,cnt_d; GString *str; GString *open; GError *err=NULL; if (!g_file_get_contents(argc>1?argv[1]:"/dev/stdin",&contents,&len,&err)) { fprintf(stderr,"%s: %s\n",argc>1?argv[1]:"stdin",err->message); exit(1); } open=g_string_new(NULL); paras=g_strsplit(contents,"\n\n",0); g_free(contents); for(i=0;paras[i];i++) { str=g_string_new(NULL); s=plain_text(paras[i]); if (g_str_has_prefix(s,open->str)) { /* * Paragraph 1 elided closing quotation marks; paragraph * 2 starts with opening quotation marks. */ g_string_truncate(open,0); } else if (s[0]!='\'' && s[0]!='"') /* * Quotation marks span multiple paragraphs. * Ideally we would check that the opening quotation * mark is at the start of a paragraph and the * closing quotation mark is at the end of paragraph. */ ; else if (open->len) g_warning("Quotation marks at start of paragraph don't " "match open ones (%s):\n%s",open->str,paras[i]); g_free(s); for(j=0;paras[i][j];j++) { if (paras[i][j]=='\'') { if (open->len>0 && open->str[open->len-1]=='\'') { g_string_truncate(open,open->len-1); g_string_append_unichar(str,0x2019); } else { g_string_append_c(open,'\''); g_string_append_unichar(str,0x2018); } } else if (paras[i][j]=='"') { if (open->len>0 && open->str[open->len-1]=='"') { g_string_truncate(open,open->len-1); g_string_append_unichar(str,0x201D); } else { g_string_append_c(open,'"'); g_string_append_unichar(str,0x201C); } } else g_string_append_c(str,paras[i][j]); } g_free(paras[i]); paras[i]=g_string_free(str,FALSE); } if (open->len) g_warning("Unclosed quotation marks: %s",open->str); g_string_free(open,TRUE); contents=g_strjoinv("\n\n",paras); g_strfreev(paras); printf("%s",contents); g_free(contents); exit(0); }