home *** CD-ROM | disk | FTP | other *** search
- // Printout is in \foo.c
- // Still need to create .PRJ file.
-
- // Doesn't handle text containing { or }.
- // All calls to Parse() need error checking.
- // Check header documentation, such as "To compile" note.
- // Search for this:
- // puts("XXX Error--Improve this error handling!");
- // Search for all XXX occurrences, which represent code to improve.
- // Maybe a feature that creates an index or table of contents?
-
- // Ask on WINSDK
- // - How to specify bold or italic?
- // - What's the max length of a line in HC.EXE?
- // - How do you create a table of contents?
-
- /* ==========================================================
- File: MH.C -- MiniHelp
- What it is: Simplifies the creation of help topic files
- by converting dot commands to RTF.
- Also eliminates the need for an RTF editor
- when creating simple help files.
- Compiler: ANSI C
- By: Tom Campbell
- Notes:
- To compile: Link with
-
- Example using Borland C:
-
- bcc mh.c
-
- Example using Microsoft C:
-
- cl mh.c
-
-
- To test:
-
- To run:
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ========================================================== */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- /* ==========================================================
- TYPE DECLARATIONS
- ========================================================== */
-
- typedef int BOOL;
- typedef unsigned WORD;
-
- /* ==========================================================
- FUNCTION DECLARATIONS
- ========================================================== */
-
- void AddExtension(char *str, char *ext);
- int CreateHelpFromMetascript(char *InFilename,
- char *OutFilename, BOOL MakeTopicKeyword);
- void CreateKeyword(FILE *OutFile, char *Keyword, int Line);
- void CreateTitle(FILE *OutFile, char *Title, int Line);
- void Error(int Line, char *Msg);
- int HasExtension(char *Filename);
- int Parse(char *Input, char *Separators, WORD StartAt,
- BOOL ForceUpper, WORD MaxLen,
- char *Buffer);
- int PossibleLinkInLine(FILE *OutFile, char *NextLine,
- WORD StartAt, int LineNo);
- void Quit(char *Msg, int ErrorLevel);
- void ReplaceExtension(char *Filename, char *Ext);
- int StripExtension(char *input);
- int UpStr(char *Str);
- void WriteChars(FILE *OutFile, char *Line, int Count,
- int LineNo);
- void WriteLine(FILE *OutFile, char *Line, int LineNo);
-
- /* ==========================================================
- CONSTANTS
- ========================================================== */
-
- #define FALSE 0
- #define TRUE (!FALSE)
- #define MAX_LINE 500
- #define MAX_FILENAME 140
-
-
- /* ==========================================================
- AddExtension()
- ========================================================== */
-
- void AddExtension(char *str, char *ext)
-
- /* ==========================================================
- What it does:
- Adds the ext to str if str doesn't already have an extension.
- A period by itself counts as an extension.
- Samples:
- AddExtension("foobar", "bak") == "foobar.bak"
- AddExtension("combat.", "lib") == "combat."
- AddExtension("vid.obj", ".bak"). == "vid.obj"
-
- Parameters:
- str : Filename w/out extension.
-
- ext : Desired extension.
-
- Returns:
- TRUE on success.
- FALSE on failure.
-
- Before calling:
- The file must be opened with dbfUse().
-
- Standard #include files required:
- string.h
-
- See also:
- HasExtension(), ReplaceExtension()
-
- Example:
- char request[80], response[80];
- printf("\n\nTesting AddExtension(). Please enter a string or \"q\" to quit. ");
- gets(request);
- printf("\nAdd what extension? ");
- gets(response);
- AddExtension(request, response);
- printf("\nResult: \"%s\"", request);
-
-
- Copyright 1992 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
-
- char *index;
- index = strchr(str, '.'); /* Is there a period in the filename? */
- if (index == NULL) { /* No. It's safe to add an extension. */
- str = strcat(str, "."); /* Append a period, */
- str = strcat(str, ext); /* then then extension. */
- }
- else { /* Yes, there was an extension. Write over */
- /* str = str + (index-str); */
- strcpy(++index, ext);
- }
-
- } /* AddExtension() */
-
- /* ========================================================== */
- void Error(int Line, char *Msg)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Displays the line number and the provided error message.
-
- If the line number is 0, doesn't print it (used in a
- case where it's irrelevant, such as not being able to
- create the output file).
-
- Parameters:
- Line : Line number error occurred on.
-
- Msg : Text of error message.
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- if (Error)
- printf("Error on line %d: %s\n", Line, Msg);
- else
- printf("Error: %s\n", Msg);
-
- } /* Error() */
-
-
- /* ========================================================== */
- int HasExtension(char *Filename)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Determines whether the specified DOS filename has an
- extension.
-
- Parameters:
- *Filename : File specification, possibly with an
- extension.
-
- Returns:
- Character position in array of extension if present.
- 0 if not.
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- int LastPossible, Length;
- Length = strlen(Filename);
- if (Length < 2)
- return 0;
- LastPossible = Length-1;
- while(LastPossible) {
- if (Filename[LastPossible] == '.')
- return LastPossible;
- else
- LastPossible--;
- }
- return 0;
- } /* HasExtension() */
-
- /* ==========================================================
- Parse()
- ========================================================== */
-
- int Parse(char *Input, char *Separators, WORD StartAt,
- BOOL ForceUpper, WORD MaxLen,
- char *Buffer)
-
- /* ==========================================================
- What it does:
- Copies the next word or token or whatever from Input and
- copies it into Buffer.
-
- Parameters:
- Input : String to be separators into tokens.
-
- Separators : Characters to be used as token delimiters.
-
- StartAt : Index of character at which to start parsing.
-
- ForceUpper : If TRUE, forces the output (which is copied
- to Buffer) to uppercase.
-
- MaxLen : Maximum # of chars to be copied into Buffer.
-
- Buffer : Buffer at least MaxLen chars wide to hold the
- output.
-
- Returns:
- Character position in string after the routine
- was called.
-
- 0 if had to return due to error condition, such as a
- separator or input string of length 0.
-
- Standard #include files required:
- string.h
- ctype.h
-
- Example:
- void main(void)
- {
-
- #define MAX_LEN 100
- int EndedAt;
- char Input[MAX_LEN];
- int Len;
- char Separators[MAX_LEN];
- WORD StartAt = 0;
- BOOL ForceUpper = FALSE;
- WORD MaxLen = MAX_LEN;
- #define MAX_TOKEN 5
- char Buffer[MAX_TOKEN + 1];
-
- do {
- Input[0] = '\0';
- printf("String to parse: ");
- gets(Input);
- if (Input[0]) {
- printf("Separators: ");
- gets(Separators);
- StartAt = 0;
- do {
- Len = strlen(Input);
- EndedAt = Parse(Input, Separators, StartAt,
- ForceUpper, MAX_TOKEN, Buffer);
- printf(
- "Parsed string: \"%s\"\nEnded parse at: %d\n",
- Buffer, EndedAt);
- StartAt = EndedAt;
- } while(EndedAt < Len);
- puts("");
- }
-
-
- } while (Input[0] != '\0');
- }
-
- Copyright 1992 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- /* Character currently being processed. */
- int Ch;
-
- /* # of chars in return value. */
- WORD Count = 0;
-
- /* Loop counter. */
- int Index;
-
- /* Length of input string. */
- int TextLen = strlen(Input);
-
- /* Position in Input of any separator character(s). */
- char *SepPos;
-
- /* Exit immediately if there's no input, or there are no
- separators specified, or if the position to start at
- is outside the string. */
- if ( (!&Input[StartAt]) || (!Separators) || (StartAt > TextLen) )
- return 0;
-
- /* Loop through each char of the input string. */
- for (Index = StartAt; Index < TextLen; Index++) {
-
- /* Quit if reached the maximum length for the output
- token. */
- if (Count >= MaxLen) {
-
- /* Make this a C string. */
- Buffer[Count] = '\0';
-
- /* Return the current position in the string. */
- return Index;
-
- }
-
- /* Get the next character from the input. */
- Ch = Input[Index];
-
- /* Force to uppercase if necessary. */
- if (ForceUpper)
- Ch = toupper(Ch);
-
- /* See if this is a separator. */
- SepPos = strchr(Separators, Ch);
-
- /* Remove separators. */
- if (SepPos) {
-
- /* If here, you're on trailing separators. That means
- it's time to quit. */
- if (Count > 0) {
-
- /* Make this a C string. */
- Buffer[Count] = '\0';
-
- /* Return the current position int the string. */
- return Index;
-
- } /* if Count */
-
- } /* if SepPos */
-
- else {
- /* Add to string if not a separator. */
-
- /* Make it a C string. */
- Buffer[Count] = Ch;
-
- /* Track # of chars in string. */
- Count++;
-
- } /* if SepPos */
-
- } /* for Index */
-
- /* Make this a C string. */
- Buffer[Count] = '\0';
-
- /* Return position in input string. */
- return Index;
-
- } /* Parse() */
-
-
- /* ========================================================== */
- void Quit(char *Msg, int ErrorLevel)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Displays the provided error message and exits to DOS,
- setting the supplied error code.
-
- Parameters:
- Msg : Text of error message.
-
- ErrorLevel : ERRORLEVEL is set to this value.
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- puts(Msg);
- exit(ErrorLevel);
-
- } /* Quit() */
-
-
- /* ==========================================================
- ReplaceExtension()
- ========================================================== */
-
- void ReplaceExtension(char *Filename, char *Ext)
-
- /* ==========================================================
- What it does:
- Replaces the extension of Filename.
-
- Parameters:
- DBF : Pointer to information for the .DBF file.
-
- Returns:
- TRUE on success.
- FALSE on failure.
-
- Before calling:
- The file must be opened with dbfUse().
-
- Example:
- if (!HasExtension(DBF->FullPathNameStr))
- ReplaceExtension(DBF->FullPathNameStr, "DBF");
-
- See also:
- AddExtension(), HasExtension()
-
- Copyright 1992 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
-
- StripExtension(Filename);
- AddExtension(Filename, Ext);
-
- } /* ReplaceExtension() */
-
-
- /* ==========================================================
- StripExtension()
- ========================================================== */
-
- int StripExtension(char *input)
-
- /* ==========================================================
- What it does:
- If input ends in a dot and up to 3 letters, returns it
- without the dot and letters.
-
- Parameters:
- input : Filename, such as "ACCOUNTS.DBF".
-
- Returns:
- -1 and new string in intput if a change was made.
- 0 and input if no change was made.
-
- Standard #include files required:
- string.h
-
- See also:
- HasExtension(), ReplaceExtension()
-
- Example 1.
- if(StripExtension(response))
- printf("\nResult: \"%s\"", response);
- else
- puts("No change made.");
-
- Example 2.
- void main(void)
- {
- int EachChar;
-
- char Input[100], Output[100];
-
- int Changed;
-
- do {
- Input[0] = '\0';
-
- printf("Please enter a filename, or ");
- printf("[Enter by itself to quit\n> ");
- fflush(stdin);
- gets(Input);
- if (Input[0] == '\0')
- exit(0);
- Changed = StripExtension(Input);
- if (Changed)
- printf("Extension was removed. ");
- printf("String is now:\n\n\t%s\n", Input);
- else
- puts("String had no extension and was unchanged.");
-
- } while( (Input[0] != '\0') ||
- (!stricmp(Input, "quit")) );
- }
-
- Notes:
- Even handles (correctly) such pathologically weird
- input as "a.b\c", in which the period is not an
- extension and should therefore not be removed.
-
- Copyright 1992 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- /* If input has an extension, this points to it. */
- char *dot;
-
- /* If input has one or more backslashes, this is the one
- closes to the end. */
- char *backslash;
-
- /* Length of input string. */
- int inlen;
-
- /* Where to start looking in input for the dot. */
- char *start;
-
- /* We have to start at the end of the string, due to the remote
- possibility of a pathname whose directory entries contain
- extensions. */
-
- /* Length of input. */
- inlen = strlen(input);
- /* Dot must be in final 4 chars. */
- inlen -= 4;
- /* Point at last chars of string. */
- start = input + inlen;
-
- /* Search for last dot in the input. */
- dot = strrchr(start, '.');
-
- /* Search for the last backslash. */
- backslash = strrchr(start, '\\');
-
- /* If it's after the dot, there's no extension. */
- if (dot)
- if (backslash > dot)
- /* Despite the presence of both backslash and dot, exit
- doing nothing because the backslash follows the
- dot. */
- return 0;
-
- /* Extension found at end of string. */
- if (dot != NULL) {
- dot[0] = '\0';
- /* strcpy(output, input); */
- /* Return with success code. */
- return -1;
- }
-
- /* No extension found. */
- else
- /* Quit with failure code. */
- return 0;
-
- } /* StripExtension() */
-
- /* ==========================================================
- UpStr()
- ========================================================== */
-
- int UpStr(char *Str)
-
- /* ==========================================================
- What it does:
- Forces string *Str to uppercase.
-
- Parameters:
- *Str : String to force to uppercase.
-
- Returns:
- # of characters in string.
-
- Standard #include files required:
- ctype.h, string.h
-
- Example:
- if (Input[0]) {
- Len = UpStr(Input);
- printf("Converted %d chars to string: \"%s\"\n",
- Len, Input);
- }
-
- Copyright 1992 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- /* Loop counter. */
- int EachChar;
-
- /* String length value. */
- int Len;
-
- /* Get length of string to convert. */
- Len = strlen(Str);
-
- /* Loop through each character of the string, converting
- to uppercase. */
- for (EachChar = 0; EachChar < Len; EachChar++)
- Str[EachChar] = toupper(Str[EachChar]);
-
- /* Add the terminating 0. */
- Str[Len] = '\0';
-
- /* # of characters in string. */
- return Len;
-
- } /* UpStr() */
-
-
-
- /* ========================================================== */
- void WriteChars(FILE *OutFile, char *Line, int Count,
- int LineNo)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Writes the the specified number of characters to
- the output file. Does not look for a terminating
- 0, as does WriteLine().
-
- If unable to, exits to OS with an appropriate
- error message.
-
- Parameters:
- OutFile : Descriptor of file open for output.
-
- Count : # of chars to write.
-
- Line : Text to write.
-
- LineNo : Current line number in OutFile.
-
- Before calling:
- Open OutFile with read/write access in text mode.
-
- Standard #include files required:
- stdio.h
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
-
- if (fwrite(Line, Count, 1, OutFile) != 1) {
- Error(LineNo, "Unable to write to output file.");
- Quit("", 1);
- }
-
- } /* WriteChars() */
-
-
- /* ========================================================== */
- void WriteLine(FILE *OutFile, char *Line, int LineNo)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Writes the supplied line to the supplied file.
- If unable to, exits to OS with an appropriate
- error message.
-
- Parameters:
- OutFile : Descriptor of file open for output.
-
- Line : Text to write.
-
- LineNo : Current line number in OutFile.
-
- Before calling:
- Open OutFile with read/write access in text mode.
-
- Standard #include files required:
- stdio.h
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
-
- if (fwrite(Line, strlen(Line), 1, OutFile) != 1) {
- Error(LineNo, "Unable to write to output file.");
- Quit("", 1);
- }
-
- } /* WriteLine() */
-
-
- /* ========================================================== */
- void CreateKeyword(FILE *OutFile, char *Keyword, int Line)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Creates a keyword topic in the RTF file.
-
- Ends with a newline for clarity.
-
- Parameters:
- OutFile : RTF output file.
-
- *Keyword : String with keyword entry.
-
- Line : Line number of input source file.
-
- Before calling:
- Open *OutFile.
-
- Standard #include files required:
- stdio.h
-
- See also:
- CreateTitle()
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- WriteLine(OutFile, "K{\\footnote ", Line);
- WriteLine(OutFile, Keyword, Line);
- WriteLine(OutFile, "}\n", Line);
- } /* CreateKeyword() */
-
-
- /* ========================================================== */
- void CreateLink(FILE *OutFile, char *LinkName, char *LinkText, int Line)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Creates a link in the RTF file.
-
- Parameters:
- OutFile : RTF output file.
-
- *LinkName: String with link name.
-
- *LinkText : String with link text.
-
- Line : Line number of input source file.
-
- Before calling:
- Open *OutFile.
-
- Standard #include files required:
- stdio.h
-
- See also:
- CreateTitle()
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- /* This will be used to see if the last char on the line
- is a space. */
- int Len = strlen(LinkText);
-
- /* Flags whether a trailing space need be added. */
- BOOL PadEnd;
- if (Len)
- Len--;
- else
- /* XXX Length of 0 is an error! */
- return;
-
- /* Special case: A space after the first quote is replaced
- by a space *preceding* the link. */
- if (LinkText[0] == ' ') {
- WriteLine(OutFile, " ", Line);
- LinkText++;
- Len--;
- }
-
- /* Likewise for a trailing space. */
- if (LinkText[Len] == ' ') {
- PadEnd = TRUE;
- LinkText[Len] = '\0';
- }
-
- WriteLine(OutFile, "{\\uldb ", Line);
- WriteLine(OutFile, LinkText, Line);
- WriteLine(OutFile, "}", Line);
-
- WriteLine(OutFile, "{\\v ", Line);
- WriteLine(OutFile, LinkName, Line);
- WriteLine(OutFile, "}", Line);
-
- if (PadEnd)
- WriteLine(OutFile, " ", Line);
-
- } /* CreateLink() */
-
-
- /* ========================================================== */
- void CreateTitle(FILE *OutFile, char *Title, int Line)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Creates a title entry in the RTF file.
-
- Ends with a newline for clarity.
-
- Parameters:
- OutFile : RTF output file.
-
- *Title : String with title name.
-
- Line : Line number of input source file.
-
- Before calling:
- Open *OutFile.
-
- See also:
- CreateKeyword()
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
- WriteLine(OutFile, "${\\footnote ", Line);
- WriteLine(OutFile, Title, Line);
- WriteLine(OutFile, "}\n", Line);
- } /* CreateTitle() */
-
-
- /* ========================================================== */
- int CreateHelpFromMetascript(char *InFilename,
- char *OutFilename, BOOL MakeTopicKeyword)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Script-driven routine that takes a CHELP script and
- and creates a help source file for the Microsoft Windows
- HC.EXE compiler from the specified filename.
-
- Parameters:
- InFilename : Name of script file.
-
- OutFilename : Name of file to create.
-
- MakeTopicKeyword : If TRUE (nonzero), automatically create
- a keyword entry for teach topic.
-
- Returns:
- Nonzero on success.
- Zero on failure.
-
- Example:
- XXX
-
- Notes:
- XXX
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
-
- /* Position on line in the specified char was found. */
- int CharIndex;
-
- /* Used for the .keywords dot command to separate the
- remainder of the line (after the .keyword dot command)
- into tokens. */
- int EndedAt;
-
- /* Copy of the first token, forced to uppercase. */
- char FirstToken[MAX_LINE+1];
-
- /* Used in search for a particular char on the line
- (such as { for links). */
- char *FoundChar;
-
- /* Descriptor for script file. */
- FILE *InFile = NULL;
-
- /* Each topic must end with a \page statement. If the .TOPIC
- dot command is found and InTopic is TRUE, it means a topic
- had been started and it's time to close it off with a
- \page. Ditto for a file with only 1 topic and EOF is
- reached. */
- BOOL InTopic = FALSE;
-
- /* # of line being processed. */
- int Line = 0;
-
- /* # of chars in line. */
- int LineLen;
-
- /* The symbolic name of the link itself, used in the help
- compiler's symbol table. */
- char LinkName[MAX_LINE+1];
-
- /* The text shown in place of the link; in quotes after the
- .LINK's link name. */
- char LinkText[MAX_LINE+1];
-
- /* Buffer for each line read from the script file. */
- char NextLine[MAX_LINE+1];
-
- /* Successive tokens after the first one. */
- char NextToken[MAX_LINE+1];
-
- /* Descriptor for file created by this program. */
- FILE *OutFile = NULL;
-
- /* Token delimiters. */
- /* char Separators[] = " ,\t\n-/:"; */
- char Separators[] = " \n";
-
- /* Starting position of next token in the line. */
- int StartNext;
-
- /* Each topic should have a title (if it doesn't, HC
- creates a warning and puts an "<<Unititled topic>>"
- in the .HLP output file). */
- BOOL TopicHasTitle = FALSE;
-
- /* Name of topic is used instead of FirstToken because
- it might also be used to generate a title. */
- char TopicName[MAX_LINE+1];
-
- /* Open the script file in text mode, read-only access. */
- InFile = fopen(InFilename, "r");
- if (!InFile) {
- puts("XXX Unable to open script file.");
- return 0;
- }
-
- /* Create the output file in text mode, read/write access. */
- OutFile = fopen(OutFilename, "wt");
- if (!OutFile) {
- Error(0, "Unable to create output file");
- Quit("", 1);
- }
-
- /* Create the prolog. */
- Line++;
- WriteLine(OutFile, "{\\rtf1\\ansi \\deff2\n", Line);
- Line++;
- WriteLine(OutFile, "{\\fonttbl\n", Line);
- Line++;
- WriteLine(OutFile, "{\\f0\\froman Times New Roman;}\n", Line);
- Line++;
- WriteLine(OutFile, "{\\f1\\fdecor Courier New;}\n", Line);
- Line++;
- WriteLine(OutFile, "{\\f2\\fswiss Arial;}\n", Line);
- Line++;
- WriteLine(OutFile, "}\n", Line);
-
- /* ==========================================================
- MAIN LOOP
- ========================================================== */
-
- while (1) {
-
- /* Copy the next line of the file into NextLine. */
- if (fgets(NextLine, MAX_LINE, InFile)== NULL)
- break;
-
- /* Track line number of source file. */
- Line++;
-
- /* ==========================================================
- Force a copy of the first token to uppercase
- ========================================================== */
-
- /* Get the first token from NextLine.
- Use the characters defined in Separators as token separators.
- Start at position 0.
- The 1 means force to uppercase.
- Copy only MAX_LINE or less characters to the output buffer,
- which is FirstToken.
-
- Write the position of the character after the first token
- in StartNext. */
- StartNext = Parse(NextLine, Separators, 0, 1, MAX_LINE, FirstToken);
-
- /* Don't process if it's a comment line. */
- if (FirstToken[0] == ';') {
- continue;
- }
-
- /* ==========================================================
- Link
-
- Example:
-
- Try the
- .link EditMenu "Edit Menu"
- for more information.
-
- Generates this text in the output file:
-
- Try the {\uldb Edit Menu}{\v EditMenu} for more information.
-
- ========================================================== */
-
- if (!strcmp(FirstToken, ".LINK")) {
-
- /* Get the link name. */
- StartNext = Parse(NextLine, Separators, StartNext, 0,
- MAX_LINE, NextToken);
-
- /* Get the quoted link text. */
- StartNext = Parse(NextLine, "\"", StartNext+1, 0,
- MAX_LINE, LinkText);
-
- CreateLink(OutFile, NextToken, LinkText, Line);
- /* Go to top of loop. */
- continue;
-
- }
-
- /* ==========================================================
- Topic
-
- Example:
-
- .topic MenuEdit
-
- Generates this text in the output file, followed by
- a newline:
-
- #{\footnote MenuEdit}
-
- ========================================================== */
-
- if (!strcmp(FirstToken, ".TOPIC")) {
-
- /* Write out the \page if we were in a topic already;
- this means we're starting a new one. */
- if (InTopic) {
- WriteLine(OutFile, "\\page\n", Line);
- Line++;
- }
-
- /* Note that we're in a new topic. */
- InTopic = TRUE;
-
- /* Each topic should have a title. The topic
- text will be used to generate one if the
- .topic dot command doesn't show up. */
- TopicHasTitle = FALSE;
-
- /* Get the topic name. */
- StartNext = Parse(NextLine, Separators, StartNext, 0,
- MAX_LINE, TopicName);
-
- /* Write out the topic flag, a # footnote.
- Also write out a newline for clarity. */
- WriteLine(OutFile, "#{\\footnote ", Line);
- WriteLine(OutFile, TopicName, Line);
- WriteLine(OutFile, "}\n", Line);
- Line++;
-
- /* If desired, automatically create a keyword for this
- topic. */
- if (MakeTopicKeyword) {
- CreateKeyword(OutFile, TopicName, Line);
- Line++;
- }
-
- /* Go to top of loop. */
- continue;
-
- }
-
- /* ==========================================================
- Title
-
- Example:
-
- .title Edit Menu
-
- Generates this text in the output file, followed by
- a newline:
-
- ${\footnote Edit Menu}
-
- ========================================================== */
-
- if (!strcmp(FirstToken, ".TITLE")) {
-
- /* Note that this topic has a title. */
- TopicHasTitle = TRUE;
-
- WriteLine(OutFile, "${\\footnote ", Line);
- WriteLine(OutFile, &NextLine[++StartNext], Line);
- WriteLine(OutFile, "}\n", Line);
- Line++;
-
- /* Go to top of loop. */
- continue;
-
- }
-
- /* ==========================================================
- Keywords
- They can have spaces. Separated by semicolons.
-
- Example:
-
- .Keyword Search; Find and Replace; Look for
-
- ========================================================== */
- if (!strcmp(FirstToken, ".KEYWORD") || !strcmp(FirstToken, ".KEYWORDS")) {
-
- LineLen = strlen(NextLine) - StartNext;
-
- /* Loop for all keywords on the line. */
- do {
- EndedAt = Parse(NextLine, ";\n", StartNext,
- 0, MAX_LINE, NextToken);
- CreateKeyword(OutFile, NextToken, Line);
- Line++;
- StartNext = EndedAt;
- } while(EndedAt < LineLen);
-
- /* Go to top of loop. */
- continue;
-
- }
-
- /* ==========================================================
- Blank line
-
- Blank lines are significant in the source files; they're
- turned into RTF newline (\par) commands.
-
- ========================================================== */
- if (!strcmp(NextLine, "\n")) {
-
- WriteLine(OutFile, "\\par\n", Line);
- Line++;
- /*Go to top of loop. */
- continue;
-
- }
-
- /* ==========================================================
- FontSize
-
- Example:
-
- .FontSize 10
-
- ========================================================== */
-
- if (!strcmp(FirstToken, ".FONTSIZE")) {
-
- /* Converted from ASCII. Note that the /fs RTF commmand
- is in half points, so we double the value given. */
- int FontSize;
-
- /* Get the font size specified. */
- StartNext = Parse(NextLine, Separators, StartNext, 0,
- MAX_LINE, NextToken);
-
- sscanf(NextToken, "%d", &FontSize);
- FontSize *= 2;
- sprintf(NextToken, "\n\\fs%d\n", FontSize);
- WriteLine(OutFile, NextToken, Line);
-
- Line++;
-
- /* Go to top of loop. */
- continue;
-
- }
-
-
- /* ==========================================================
- Links
- ========================================================== */
- FoundChar = strchr(NextLine, '{');
-
- /* Found the opening { for a link. */
- if (FoundChar) {
-
- /* Position on which { was found. */
- CharIndex = FoundChar - NextLine;
-
- /* There may be a link on this line. If at least one, returns
- TRUE. If not, returns FALSE, so drop through to the
- default action. */
- if (PossibleLinkInLine(OutFile, NextLine, CharIndex, Line))
- /* Go to top of loop. */
- continue;
-
- }
-
- /* ==========================================================
- Default: Write out the line as is.
- If there wasn't a .title dot command for this topic,
- generate it from the topic name.
- ========================================================== */
- if (TopicHasTitle == FALSE) {
-
- CreateTitle(OutFile, TopicName, Line);
- Line++;
-
- /* But do this only once. */
- TopicHasTitle = TRUE;
- }
-
- WriteLine(OutFile, NextLine, Line);
- Line++;
-
- } /* while */
-
- /* ==========================================================
- END OF TOPIC FILE
- Write out the end-of-topic \page marker.
- ========================================================== */
-
- /* Write out the \page if we were in a topic. */
- if (InTopic) {
- WriteLine(OutFile, "\\page", Line);
- Line++;
- }
-
- /* The file must open with a brace and--here--close with
- a brace. */
- Line++;
- WriteLine(OutFile, "\n}", Line);
-
- fclose(InFile);
- fclose(OutFile);
-
- /* Nonzero means no error occurred. */
- return -1;
-
- } /* CreateHelpFromMetascript() */
-
-
- /* ========================================================== */
- int PossibleLinkInLine(FILE *OutFile, char *NextLine,
- WORD StartAt, int LineNo)
- /* ========================================================== */
-
- /* ==========================================================
- What it does:
- Some lines have embedded links like this:
-
- See the {main dictionary:dict1} for a defintion.
-
- This means that the text "main dictionary" will be
- highlighted, but pressing Enter on the highlighted
- text will go to a link named dict1, not
- "main dictionary". And the "dict1" doesn't appear.
-
- At this point the first { has been sighted. We don't know
- if the line contains a link or not.
-
- This is all complicated by the allowance of more than
- one link per line. Not only do we allow escaping the
- { so that it can be used, multiple links make the
- processing quite complicated. A line like this is
- suspected to have a link when this routine is called
- but actually doesn't:
-
- The curly brace (\{) starts a compound statement.
-
- Parameters:
- OutFile : RTF Help output file.
-
- NextLine : Line of text from the source file.
-
- StartAt : Position where the { was found.
-
- LineNo : Current source line number.
-
- See also:
- XXX
-
- Example:
- XXX
-
- Notes:
- XXX
-
- Copyright 1993 by Tom Campbell. All rights reserved.
- ======================================================== */
- {
-
- /* Position on line in the specified char was found. */
- int CharIndex;
-
- /* Used in search for a particular char on the line
- (such as { for links). */
- char *FoundChar;
-
- /* Length of the entire input line, starting with position
- 0, not StartAt. */
- int LineLen = strlen(NextLine);
-
- /* The symbolic name of the link itself, used in the help
- compiler's symbol table. */
- char *LinkName;
-
- /* The text shown in place of the link; in quotes after the
- .LINK's link name. */
- char *LinkText;
-
- /* Starting position of next token in the line. */
- int StartNext;
-
- /* Allocate LinkName and LinkText dynamically because this
- routine might be called recursively. */
- LinkName = malloc((MAX_LINE+1) * sizeof(char));
- if (LinkName == NULL) {
- Error(LineNo, "Out of memory.");
- Quit("", 1);
- }
-
- LinkText = malloc((MAX_LINE+1) * sizeof(char));
- if (LinkText == NULL) {
- free(LinkName);
- Error(LineNo, "Out of memory.");
- Quit("", 1);
- }
-
-
- /* Get the chars between the '{' and the ':' as in
- "LinkName" if the text of the link is
- "{LinkName:link0}". */
- StartNext = Parse(NextLine, ":", StartAt+1, 0, MAX_LINE, LinkText);
-
- /* There was an opening '{', but no ':'. */
- if (StartNext >= LineLen) {
- free(LinkText);
- free(LinkName);
- /* This line doesn't contain a valid link. */
- return FALSE;
- }
-
- /* LinkText now has the link text, which the user sees. Now
- get the symbolic link name required by the compiler.
- Force to uppercase. */
- StartNext = Parse(NextLine, "}", StartNext+1, 1, MAX_LINE, LinkName);
-
- /* There was an opening '{', and a ':', but no closing
- '}'. */
- if (StartNext >= LineLen) {
- free(LinkText);
- free(LinkName);
- /* This line doesn't contain a valid link. */
- return FALSE;
- }
-
- /* Write any characters preceding the link to the output
- file. */
- WriteChars(OutFile, NextLine, StartAt, LineNo);
-
- /* The link name and the link text, separated by a ':' and
- enclosed in curly braces, were found. Create a link. */
- CreateLink(OutFile, LinkName, LinkText, LineNo);
- free(LinkText);
- free(LinkName);
-
- /* Skip past the closing brace of the previous
- link. */
- StartNext++;
-
- FoundChar = strchr(&NextLine[StartNext], '{');
-
- /* Found the opening { for a link. */
- if (FoundChar) {
-
- /* Position on which { was found. */
- StartAt = FoundChar - &NextLine[StartNext];
-
- PossibleLinkInLine(OutFile, &NextLine[StartNext], StartAt, LineNo);
- }
- else {
- ///
- WriteChars(OutFile, &NextLine[StartNext], LineLen-StartNext, LineNo);
- LineLen += LineLen-StartNext;
- }
-
-
- /* Yes, there was a valid link. */
- return (TRUE);
-
-
- } /* PossibleLinkInLine() */
-
-
- void main(int argc, char *argv[])
- {
- /* Used when user enters a filename. */
- char InFilename[FILENAME_MAX] = "\0";
-
- /* Used to generate an error/success message. */
- char Msg[FILENAME_MAX*2];
-
- /* With this option, topics are automatically made into
- keywords. That lets them find and view them using
- the Search feature. Enable this feature
- with the -K option. */
- BOOL MakeTopicKeyword = FALSE;
-
- /* Name of file created by this program. */
- char OutFilename[FILENAME_MAX] = "\0";
-
- /* Continue while there are command-line switches or
- filenames. */
- while (argc-- && **argv++ && argc) {
- /* Cast what is normally a string pointer to an int, because
- C can think of a two-char value as an int. */
- switch (*( (int *) *argv )) {
- case '/k':
- case '-K':
- MakeTopicKeyword = TRUE;
- break;
- default:
- strcpy(InFilename, *argv);
- strcpy(OutFilename, *argv);
- if (!HasExtension(InFilename))
- ReplaceExtension(InFilename, "SRC");
- UpStr(InFilename);
- UpStr(OutFilename);
- ReplaceExtension(OutFilename, "RTF");
- if (!strcmp(InFilename, OutFilename)) {
- Quit("Input and output files have the same name.", 1);
- }
- break;
- } /* switch */
- } /* switch */
- if (InFilename[0] == 0)
- Quit("Need to specify an input file.", 1);
- if(CreateHelpFromMetascript(InFilename, OutFilename, MakeTopicKeyword)) {
- sprintf(Msg, "Created topic file \"%s\" successfully.", OutFilename);
- Quit(Msg, 0);
- }
- } /* main() */
-
-
-