00001
00008
00009
00010 #include "NMEPluginTOC.h"
00011 #include <stdlib.h>
00012
00014 #define isBlankOrEol(c) ((c) == ' ' || (c) == '\t' || (c) == 10 || (c) == 13)
00015
00016 static void switchOutputFormatTOC(HookTOCData *hookData,
00017 NMEBoolean heading);
00018
00031 static NMEErr parHookTOC(NMEInt level,
00032 NMEInt item,
00033 NMEBoolean enter,
00034 NMEConstText markup,
00035 NMEInt srcIndex,
00036 NMEInt srcLineNumber,
00037 NMEContext *context,
00038 void *data)
00039 {
00040 HookTOCData *d = (HookTOCData *)data;
00041
00042 if (markup[0] == '=' && level >= d->level1 && level <= d->level2)
00043 switchOutputFormatTOC(d, enter);
00044
00045 return kNMEErrOk;
00046 }
00047
00052 static void switchOutputFormatTOC(HookTOCData *hookData,
00053 NMEBoolean heading)
00054 {
00055 if (heading)
00056 {
00057 *hookData->outputFormat = NMEOutputFormatHTML;
00058 hookData->outputFormat->beginHeading
00059 = "%%{l} %%<a href=\"#h%{o}\">%%{i>0}%{i}. %%";
00060 hookData->outputFormat->endHeading = "</a><br />\n";
00061 hookData->outputFormat->lineBreak = " ";
00062 hookData->outputFormat->beginLink = "";
00063 hookData->outputFormat->endLink = "";
00064 hookData->outputFormat->sepLink = NULL;
00065 hookData->outputFormat->beginImage = "";
00066 hookData->outputFormat->endImage = "";
00067 hookData->outputFormat->sepImage = NULL;
00068 }
00069 else
00070 {
00071 *hookData->outputFormat = NMEOutputFormatNull;
00072 hookData->outputFormat->beginDoc
00073 = "<html>\n<body>\n<p%%{s>0} style=\"font-size:%{s}pt\"%%>\n";
00074 hookData->outputFormat->endDoc = "</p>\n</body>\n</html>\n";
00075 }
00076 hookData->outputFormat->parHookFun = parHookTOC;
00077 hookData->outputFormat->hookData = (void *)hookData;
00078 }
00079
00080 void NMESetTOCOutputFormat(NMEOutputFormat *f, HookTOCData *d)
00081 {
00082 d->level1 = 1;
00083 d->level2 = 4;
00084 d->links = TRUE;
00085 d->outputFormat = f;
00086 switchOutputFormatTOC(d, FALSE);
00087 }
00088
00089 NMEErr NMEPluginTOC(NMEConstText name, NMEInt nameLen,
00090 NMEConstText data, NMEInt dataLen,
00091 NMEContext *context,
00092 void *userData)
00093 {
00094 char *endp;
00095 HookTOCData hookData;
00096 NMEText title, buf, dest;
00097 NMEInt titleLen, bufLen, destLen;
00098 NMEOutputFormat outputFormat;
00099 NMEInt options, fontSize;
00100 NMEErr err;
00101 (void)name;
00102 (void)nameLen;
00103
00104 NMESetTOCOutputFormat(&outputFormat, &hookData);
00105
00106
00107 hookData.level1 = strtol(data, &endp, 0);
00108 hookData.level2 = strtol(endp, &endp, 0);
00109 if (hookData.level1 < 1)
00110 return kNMEErrOk;
00111 if (hookData.level2 < hookData.level1)
00112 hookData.level2 = hookData.level1;
00113
00114
00115 for (title = endp; title < data + dataLen && isBlankOrEol(title[0]); title++)
00116 ;
00117 for (titleLen = dataLen - (title - data);
00118 titleLen > 0 && isBlankOrEol(title[titleLen - 1]);
00119 titleLen--)
00120 ;
00121
00122
00123 NMEGetTempMemory(context, &buf, &bufLen);
00124 NMEGetFormat(context, NULL, &options, &fontSize);
00125 err = NMEProcess(((NMEPluginTocData *)userData)->src,
00126 ((NMEPluginTocData *)userData)->srcLen,
00127 buf, bufLen,
00128 options | kNMEProcessOptNoPreAndPost, "\n", &outputFormat, fontSize,
00129 &dest, &destLen, NULL);
00130 if (err != kNMEErrOk)
00131 return err;
00132
00133
00134 if (titleLen > 0)
00135 if (!NMEAddString("<h2%%{s>0} style=\"font-size:%{2*s}pt\"%%>", -1, '%', context)
00136 || !NMEAddString(title, titleLen, '\0', context)
00137 || !NMEAddString("</h2>\n", -1, '%', context))
00138 return kNMEErrNotEnoughMemory;
00139
00140
00141 if (!NMEAddString("<p%%{s>0} style=\"font-size:%{s}pt\"%%>\n", -1, '%', context)
00142 || !NMEAddString(dest, destLen, '\0', context)
00143 || !NMEAddString("</p>\n", -1, '%', context))
00144 return kNMEErrNotEnoughMemory;
00145
00146 return kNMEErrOk;
00147 }