Latex does not provide the Chinese Word Count statistics function like word. In addition, the latex source file contains many control characters, so you cannot know the number of Chinese characters in the file size. Therefore, I used C to write a small tool for counting Chinese characters, called CWC, that is, Chinese Word counter. This program only uses Windows APIs for the count_files () function, and can be transplanted to Linux/Unix with slight modifications.
# Include <stdio. h>
# Include <wchar. h>
# Include <windows. h>
Int Total = 0; // total Chinese Characters
// Unicode version word counter
Void word_count_u (File * PF)
{
Int W = 0, B = 2;
Wint_t C;
While (C = getwc (PF ))! = Weof ){
B + = 2; // Byte Count
If (C> 127) {// Chinese Character
W ++; // char count
}
}
Printf ("% 10d/T % 10d/N", W, B );
Total + = W;
}
// Word counter
Void word_count (const char * file)
{
Int W = 0, B = 0;
Int C;
Int Unicode = 0;
File * pF = fopen (file, "rb ");
If (null = PF ){
Return;
}
Printf ("% 20 s:", file );
// Determine whether it is a Unicode file
If (C = GETC (PF) = 0xff ){
Int cc;
If (Cc = GETC (PF) = 0xfe ){
Unicode = 1;
Printf ("Unicode ");
Word_count_u (PF );
}
Else {
Fseek (PF, 0, seek_set );
}
}
Else {
Ungetc (C, Pf );
}
If (! Unicode ){
Printf ("");
While (C = GETC (PF ))! = EOF ){
B ++; // Byte Count
If (C> 127) {// Chinese Character
W ++; // char count
B ++; // each Chinese Character occupies two bytes
If (C = GETC (PF) = EOF)
Break;
}
}
Printf ("% 10d/T % 10d/N", W, B );
Total + = W;
}
Fclose (PF );
}
Void count_files (const char * file)
{
Win32_find_data findfiledata;
Handle hfind = findfirstfile (file, & findfiledata );
If (invalid_handle_value = hfind ){
Fprintf (stderr, "can't find % s/n", file );
Return;
}
Do {
If (findfiledata. dwfileattributes & file_attribute_system ){
Continue;
}
If (findfiledata. dwfileattributes & file_attribute_directory ){
// Do nothing
}
Else {
Word_count (findfiledata. cfilename );
}
} While (findnextfile (hfind, & findfiledata ));
Findclose (hfind );
}
Int main (INT argc, char * argv [])
{
If (1 = argc ){
// Default: Count all. Tex and. txt files in current dir
Count_files ("*. Tex ");
Count_files ("*. txt ");
}
Else {
// Get filenames from command line arguments
While (-- argc> 0 ){
Count_files (argv [argc]);
}
}
Printf ("Total: % d", total );
Return 0;
}
Another common problem is that when you use dvipdfm to generate a PDF file, you often forget to close the file in Acrobat, resulting in the following error message:
E:/projects/slidewindowreport> dvipdfm slidewindow
Slidewindow. DVI-> slidemo-pdf
Unable to open slidemo-pdf
Output file removed.
For this reason, I wrote a small tool specifically used to close the PDF file in Acrobat, named closepdf. The principle is to tell acrobat through DDE to close a PDF file. This toolkit was inspired by winedt's automatic shutdown feature (I tracked its macro code to Learn How to Use DDE to control acrobat) and its code was changed from an article on msdn. I do not understand DDE at all, but it does not impede the normal operation of the program :)
With this tool, I can write a batch file to compile and read the PDF file:
Rem this is M. bat
Latex % 1
Latex % 1
Closepdf certificate 1.pdf
Dvipdfm % 1% 2% 3% 5
Start transaction 1.pdf
The Code is as follows:
// Close the user specified PDF file in Acrobat Reader
// Ref. Microsoft Knowledge Base Article-279721
// HOWTO: Use Dynamic Data Exchange (DDE) with Word and Excel from Visual C ++
// Modified by solstice 2004/01/2
# Define win32_lean_and_mean // exclude rarely-used stuff from Windows Headers
# Define strict
# Include <windows. h>
# Include <ddeml. h>
# Include <stdio. h>
# Include <assert. h>
# Include <stdlib. h>
Hddedata callback ddecallback (
Uint utype, // transaction type.
Uint UFMT, // Clipboard data format.
Hconv, // handle to the conversation.
Hsz hsz1, // handle to a string.
Hsz hsz2, // handle to a string.
Hddedata hdata, // handle to a global memory object.
DWORD dwdata1, // transaction-specific data.
DWORD dwdata2) // transaction-specific data.
{
Return 0;
}
Void ddeexecute (DWORD idinst, hconv, char * szcommand)
{
Hddedata hdata = ddecreatedatahandle (idinst, (lpbyte) szcommand,
Lstrlen (szcommand) + 1, 0, null, cf_text, 0 );
If (hdata = NULL ){
Printf ("command failed: % s/n", szcommand );
}
Else {
Ddeclienttransaction (lpbyte) hdata, 0 xffffffff, hconv, 0l, 0,
Xtyp_execute, timeout_async, null );
}
}
Void dderequest (DWORD idinst, hconv, char * szitem, char * sdesc)
{
Hsz hszitem = ddecreatestringhandle (idinst, szitem, 0 );
Hddedata hdata = ddeclienttransaction (null, 0, hconv, hszitem, cf_text,
Xtyp_request, 5000, null );
If (hdata = NULL)
{
Printf ("request failed: % s/n", szitem );
}
Else
{
Char szresult [255];
Ddegetdata (hdata, (unsigned char *) szresult, 255, 0 );
Printf ("% S % s/n", sdesc, szresult );
}
}
Void ddepoke (DWORD idinst, hconv, char * szitem, char * szdata)
{
Hsz hszitem = ddecreatestringhandle (idinst, szitem, 0 );
Ddeclienttransaction (lpbyte) szdata, (DWORD) (lstrlen (szdata) + 1 ),
Hconv, hszitem, cf_text,
Xtyp_poke, 3000, null );
Ddefreestringhandle (idinst, hszitem );
}
Int get_error (const char * filename)
{
Handle hfile = createfile (filename,
Generic_write,
File_pai_read,
Null,
Open_existing,
File_attribute_normal,
Null );
If (invalid_handle_value = hfile ){
Return getlasterror ();
} Else {
Closehandle (hfile );
Return 0;
}
}
Bool is_file_locked (const char * filename)
{
Return (get_error (filename) = 32 );
}
Bool is_file_exists (const char * filename)
{
Return (get_error (filename )! = 2 );
}
Int main (INT argc, char * argv [])
{
Char szapp [] = "preview View ";
Char sztopic [] = "control ";
Char szcloseall [] = "[closealldocs ()]";
Char full_file_name [max_path];
Const char * file_to_close = argv [1];
If (argc = 1 ){
// Close all PDF files
} Else {// close the specified file
If (! Is_file_exists (file_to_close )){
Printf ("% s doesn't exists./N", file_to_close );
Return 1;
}
If (is_file_locked (file_to_close )){
Printf ("% s is open, trying to close it.../N", file_to_close );
} Else {
Printf ("% s is closed./N", file_to_close );
Return 0;
}
Assert (getfullpathname (
File_to_close,
Sizeof (full_file_name ),
Full_file_name,
Null
)> 0 );
// Printf ("Full name:/" % S/"/N", full_file_name );
}
// [Docopen ("" % P/%nen "")]
// [Docclose ("" % P/%nse "")]
// DDE Initialization
DWORD idinst = 0;
Uint ireturn;
Ireturn = ddeinitialize (& idinst, (pfncallback) ddecallback,
Appclass_standard | appcmd_clientonly, 0 );
If (ireturn! = Dmlerr_no_error)
{
Printf ("DDE initialization failed: 0x % 04x/N", ireturn );
Sleep (1500 );
Return 0;
}
// DDE connect to server using given appname and topic.
Hsz hszapp, hsztopic;
Hconv;
Hszapp = ddecreatestringhandle (idinst, szapp, 0 );
Hsztopic = ddecreatestringhandle (idinst, sztopic, 0 );
Hconv = ddeconnect (idinst, hszapp, hsztopic, null );
Ddefreestringhandle (idinst, hszapp );
Ddefreestringhandle (idinst, hsztopic );
If (hconv = NULL)
{
Printf ("DDE connection failed./N ");
Sleep (500); ddeuninitialize (idinst );
Return 0;
}
Else
{
Printf ("DDE connection to Acrobat Reader succeed./N ");
Sleep (50 );
}
If (argc = 1 ){
// Close all PDF files
// Execute commands/requests specific to the DDE Server.
Ddeexecute (idinst, hconv, szcloseall );
Printf ("Closing All PDF documents.../N ");
Sleep (50 );
} Else {// close the specified file
Char performance_buf [max_path + 100];
// [Docopen ("" % P/%nen "")]
// [Docclose ("" % P/%nse "")]
Printf ("Closing % s/n", full_file_name );
Snprintf (pai_buf, sizeof (pai_buf), "[docopen (/" % S/")]", full_file_name );
Ddeexecute (idinst, hconv, pai_buf );
Sleep (50 );
Snprintf (cmd_buf, sizeof (cmd_buf), "[docclose (/" % S/")]", full_file_name );
Ddeexecute (idinst, hconv, pai_buf );
Sleep (50 );
}
// DDE disconnect and uninitialize.
Ddedisconnect (hconv );
Ddeuninitialize (idinst );
If (argc = 1 ){
// Close all PDF files
Return (0 );
}
For (INT I = 0; I <5; ++ I ){
Sleep (100 );
If (! Is_file_locked (file_to_close ))
Break;
}
If (! Is_file_locked (file_to_close )){
Printf ("% s is closed./N", file_to_close );
Return 0;
} Else {
Printf ("% s is still open./N", file_to_close );
Return 1;
}
}