home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Mail / Bundles / HTMLConverter-1.0-MIHS / HTMLConverter.m < prev    next >
Encoding:
Text File  |  1997-06-16  |  8.1 KB  |  335 lines

  1. /**
  2.  **  HTMLConverter Mail Bundle
  3.  **
  4.  **/
  5.  
  6. /* C functions */
  7. /* import <stdio.h> */
  8. /* import <strings.h> */
  9.  
  10. /* Obj-C Classes */
  11. #import <appkit/appkit.h>
  12.  
  13. /* Mail stuff */
  14. #import "HTMLConverter.h"
  15.  
  16. @implementation HTMLConverter
  17.  
  18. /*****************/
  19. /* Class Methods */
  20. /*****************/
  21. + initialize;
  22. {
  23.     [NXApp addDisplayFilter:[[self alloc] init]];
  24.     return self;
  25. }
  26.  
  27. /********************/
  28. /* Instance Methods */
  29. /********************/
  30. - init;
  31. {
  32.     if (nil == [super init])
  33.         return nil;
  34.  
  35.     /* prepare instance variables */
  36.     conversionMap = nil;
  37.     htmlMapFileName = NULL;
  38.     htmlSavePathName = NULL;
  39.     htmlServiceName = NULL;
  40.     [self setFileCount:0];
  41.  
  42.     /* build the HTMLConverter file name string
  43.     and the flag on whether to convert */
  44.     [self loadDefaults];
  45.  
  46.     /* if don't convert and don't display, don't use. */
  47.     if (![self performHTMLConversion] && ![self performHTMLDisplay]) {
  48.     [self free];
  49.     return nil;
  50.     }
  51.  
  52.     /* load up the file */
  53.     if ([self performHTMLConversion]) {
  54.     [self setConversionMap:[[NXStringTable alloc] init]];
  55.     [[self conversionMap] readFromFile:[self htmlMapFileName]];
  56.     
  57.     /* if no conversion file data & not displaying, don't use. */
  58.     if ((0 == [[self conversionMap] count]) && ![self performHTMLDisplay]) {
  59.         [self free];
  60.         return nil;
  61.     }
  62.     }
  63.  
  64.     /* delete old files */
  65.     if ([self performHTMLDisplay]) {
  66.     char systemCall[MAXPATHLEN] = "rm ";
  67.     
  68.     strcat(systemCall, [self htmlSavePathName]);
  69.     strcat(systemCall, "HTMLConvert*");
  70.     system(systemCall);    /* stdlib */
  71.     }
  72.  
  73.     return self;
  74. }
  75.  
  76. - free;
  77. {
  78.     /* This doesn't malloc space for htmlMapFileName, so not freeing it. */
  79.     
  80.     [self setConversionMap:nil];
  81.  
  82.     return [super free];
  83. }
  84.  
  85. /********************/
  86. /* Accessor Methods */
  87. /********************/
  88.     /* conversion info */
  89. - (BOOL)performHTMLConversion;
  90. {
  91.     return performHTMLConversion;
  92. }
  93. - (void)setPerformHTMLConversion:(BOOL)value;
  94. {
  95.     performHTMLConversion = value;
  96. }
  97.  
  98. - (const char *)htmlMapFileName;
  99. {
  100.     return htmlMapFileName;
  101. }
  102. - (void)setHtmlMapFileName:(const char *)value;
  103. {
  104.     htmlMapFileName = value;
  105. }
  106.  
  107. - (NXStringTable *)conversionMap;
  108. {
  109.     return conversionMap;
  110. }
  111. - (void)setConversionMap:(NXStringTable *)value;
  112. {
  113.     [conversionMap free];
  114.     conversionMap = value;
  115. }
  116.  
  117.     /* display info */
  118. - (BOOL)performHTMLDisplay;
  119. {
  120.     return performHTMLDisplay;
  121. }
  122. - (void)setPerformHTMLDisplay:(BOOL)value;
  123. {
  124.     performHTMLDisplay = value;
  125. }
  126.  
  127. - (const char *)htmlSavePathName;
  128. {
  129.     return htmlSavePathName;
  130. }
  131. - (void)setHtmlSavePathName:(const char *)value;
  132. {
  133.     htmlSavePathName = value;
  134. }
  135.  
  136. - (const char *)htmlServiceName;
  137. {
  138.     return htmlServiceName;
  139. }
  140. - (void)setHtmlServiceName:(const char *)value;
  141. {
  142.     htmlServiceName = value;
  143. }
  144.  
  145. - (int)fileCount;
  146. {
  147.     return fileCount++;    /* increment for next request */
  148. }
  149. - (void)setFileCount:(int)value;
  150. {
  151.     fileCount = value;
  152. }
  153.  
  154.  
  155. /********************/
  156. - (void)loadDefaults;
  157. {
  158.     /* The values MUST be unique, else all array elements are pointers */
  159.     /*        to the exact same value! */
  160.     static NXDefaultsVector    standardDefaults = {
  161.         {"HTMLServiceName", "OmniWeb/Open URL"}
  162.         ,{"HTMLSavePathName", "/tmp/"}
  163.         ,{NULL}
  164.     };
  165.     const char *boolValue = NULL;
  166.     char path[MAXPATHLEN];
  167.     
  168.     NXRegisterDefaults([NXApp appName], standardDefaults);
  169.  
  170.     /* Should the conversion happen? */
  171.     boolValue = NULL;
  172.     boolValue = NXGetDefaultValue([NXApp appName], "HTMLConvert");
  173.     if ((NULL == boolValue) || (strcmp(boolValue, "YES") == 0)) {
  174.     [self setPerformHTMLConversion:YES];
  175.     } else {
  176.     [self setPerformHTMLConversion:NO];
  177.     }
  178.     
  179.     /* Should the display happen? */
  180.     boolValue = NULL;
  181.     boolValue = NXGetDefaultValue([NXApp appName], "HTMLDisplay");
  182.     if ((NULL == boolValue) || (strcmp(boolValue, "YES") == 0)) {
  183.     [self setPerformHTMLDisplay:YES];
  184.     } else {
  185.     [self setPerformHTMLDisplay:NO];
  186.     }
  187.     
  188.     if (![self performHTMLConversion] && ![self performHTMLDisplay]) {
  189.     /* if don't convert or display, don't need any other defaults...return */
  190.     return;
  191.     }
  192.     
  193.     
  194.     /* where is the path to use for saving */
  195.     [self setHtmlSavePathName:(const char *)NXGetDefaultValue([NXApp appName], "HTMLSavePathName")];
  196.     
  197.     /* what is the name of the service to open URLs */
  198.     [self setHtmlServiceName:(const char *)NXGetDefaultValue([NXApp appName], "HTMLServiceName")];
  199.     
  200.     /* where is the file to use for the conversion */
  201.     [self setHtmlMapFileName:(const char *)NXGetDefaultValue([NXApp appName], "HTMLMapPathFileName")];
  202.     
  203.     /* if path found, done. */
  204.     if (NULL != [self htmlMapFileName]) {
  205.     return;
  206.     }
  207.     
  208.     /* if NO path found, look in bundle */
  209.     if ([[NXBundle bundleForClass:[self class]]
  210.     getPath:path forResource:"HTMLMap" ofType:"plist"]) {
  211.         [self setHtmlMapFileName:(const char *)path];
  212.     } else {
  213.         fprintf(stderr, "*** Can't find HTMLMap.plist in bundle\n");
  214.         [self setHtmlMapFileName:(const char *)NULL];
  215.     return;
  216.     }
  217. }
  218.  
  219. - (BOOL)convertText:(Text*)text;
  220. {
  221. /*  This is how to enumerate through a hashTable (NSStringTable is subclass) */
  222.     NXStringTable *table = [self conversionMap];
  223.     const   void *key;
  224.         void *value;
  225.     NXHashState  state = [table initState];
  226.     
  227.     /* Enumerate (loop) through the key/values.  Perform conversion. */
  228.     while ([table nextState:&state key:&key value:&value]) {
  229. /*
  230. printf("test*** key:%s   value:%s\n", (const char *)key, (char *)value);
  231. */
  232.     /* have to loop through replacing multiple -keys- */
  233.     while ([text findText:key ignoreCase:YES backwards:NO wrap:YES]) {
  234.         [text replaceSel:value];
  235.     }
  236.     }
  237.     return YES;
  238. }
  239.  
  240. - (BOOL)openBrowserWithText:(Text*)text;
  241. {
  242.     Pasteboard *pboard = nil;
  243.     const char *pboardTypes[1];
  244.     char fileName[MAXPATHLEN];
  245.     char pbData[MAXPATHLEN] = "file:";
  246.     int length = 0;
  247.     
  248.     /* save Text to a file */
  249.     /* generate fileName with format like: "/tmp/HTMLConverter0.html" */
  250.     sprintf(fileName, "%sHTMLConverter%d.html", [self htmlSavePathName], [self fileCount]);
  251.     [self saveText:text toFileNamed:fileName];
  252.     
  253.     /* open file in HTML Browser through services */
  254.     /* filename with format like: "file:/tmp/HTMLConverter0.html" */
  255.     strcat(pbData, fileName);
  256.     length = strlen(pbData) + 1;
  257.     pboard = [Pasteboard newName:NXGeneralPboard];
  258.     /* Have to declare types & self as owner before able to successfully write to pboard */
  259.     pboardTypes[0] = NXAsciiPboardType;
  260.     [pboard declareTypes:pboardTypes num:1 owner:self];
  261.     [pboard writeType:NXAsciiPboardType data:pbData length:length];
  262.     
  263.     /* pboard data must include the "file:" http designation */
  264.     return NXPerformService([self htmlServiceName], pboard);
  265.     
  266.     /* standard pasteboards generally should not be freed at all. */
  267. }
  268. - (BOOL)saveText:(Text*)text toFileNamed:(const char *)filename;
  269. {
  270.     NXStream *stream;
  271.     BOOL failed = NO;
  272.     
  273.     /* open data stream */
  274.     stream = NXOpenMemory(NULL, 0, NX_READWRITE);
  275.     
  276.     if (stream) {
  277.     /* write data to stream */
  278.     NX_DURING
  279.         [text writeText:stream];
  280.     NX_HANDLER
  281.         failed = YES;
  282.     NX_ENDHANDLER
  283.     
  284.     if (!failed) {
  285.         /* write steam data to file */
  286.         NX_DURING
  287.         NXSaveToFile(stream, filename);
  288.         NX_HANDLER
  289.         failed = YES;
  290.         NX_ENDHANDLER
  291.     }
  292.     NXCloseMemory(stream, NX_FREEBUFFER);
  293.     }
  294.     
  295.     if (failed || !stream) {
  296.     NXRunAlertPanel("Error", "Couldn't save HTML to: %s", 
  297.         NULL, NULL, NULL, filename);
  298.     return NO;
  299.     }
  300.     
  301.     return YES;
  302. }
  303.  
  304.  
  305. /********************/
  306. /* Delegate Methods */
  307. /********************/
  308. - (void)willDisplayText:(Text *)text;
  309. {
  310.     /* Check if conversion is wanted & possible */
  311.     if ( !text && ([text textLength] < 10)) {
  312.     return;
  313.     }
  314.     
  315.     /* Check if conversion should be performed */
  316.     /* does <html> tag exist.  (could also check that </html> tag exists) */
  317.     if ( !([text findText:"<html>" ignoreCase:YES backwards:NO wrap:YES])) {
  318.     return;
  319.     }
  320.     
  321.     /* This Text Object does contain HTML! */
  322.  
  323.     /* if display requested, display */
  324.     if ([self performHTMLDisplay]) {
  325.     [self openBrowserWithText:text];
  326.     }
  327.  
  328.     /* if conversion requested, perform AFTER display */
  329.     if ([self performHTMLConversion]) {
  330.     [self convertText:text];
  331.     }
  332. }
  333.  
  334. @end
  335.