;+ ; NAME: ; MY_MK_HTML_HELP ; ; PURPOSE: ; Generates HTML documentation to IDL software defining hyperlinks ; to IDL source files ; ; CATEGORY: ; Help/Documentation ; ; SEE ALSO: ; MK_HTML_HELP (IDL) ; ; MODIFICATION HISTORY: ; 28 Apr 2003 Adapted from MK_HTML_HELP by Mattia Vaccari ; to generate HTML help file with hyperlinks to ; IDL source files for "LARI Package" routines ; 05 Dec 2004 Refactored for general application (Mattia Vaccari) ; 10 Mar 2006 Changed author's contact info (Mattia Vaccari) ; 05 Sep 2006 Changed author's contact info (Mattia Vaccari) ;- ;---------------------------------------------------------------------------- PRO mhh_strict, txtlines ; ; Replaces any occurrence of HTML reserved characters (<,>,&,") in the ; given text lines with the appropriate HTML counterpart. ; ; entry: ; txtlines - String array containing the text line(s) to be altered. ; exit: ; txtlines - Same as input except that reserved characters have been ; replaced with the appropriate HTML syntax. ; COMPILE_OPT hidden count = N_ELEMENTS(txtlines) FOR i=0,count-1 DO BEGIN txt = txtlines[i] ; Ampersands get replaced with &. Must do ampersands first because ; they are used to replace other reserved characters in HTML. spos = STRPOS(txt,'&') WHILE (spos NE -1) DO BEGIN newtxt = STRMID(txt,0,spos)+'&'+STRMID(txt,spos+1,STRLEN(txt)-spos+1) txt = newtxt spos = STRPOS(txt,'&',spos+1) ENDWHILE txtlines[i] = txt ; Left angle brackets get replaced with < spos = STRPOS(txt,'<') WHILE (spos NE -1) DO BEGIN newtxt = STRMID(txt,0,spos)+'<'+STRMID(txt,spos+1,STRLEN(txt)-spos+1) txt = newtxt spos = STRPOS(txt,'<',spos+1) ENDWHILE txtlines[i] = txt ; Right angle brackets get replaced with > spos = STRPOS(txt,'>') WHILE (spos NE -1) DO BEGIN newtxt = STRMID(txt,0,spos)+'>'+STRMID(txt,spos+1,STRLEN(txt)-spos+1) txt = newtxt spos = STRPOS(txt,'>',spos+1) ENDWHILE txtlines[i] = txt ; Double quotes get replaced with " spos = STRPOS(txt,'"') WHILE (spos NE -1) DO BEGIN newtxt = STRMID(txt,0,spos)+'"'+STRMID(txt,spos+1,STRLEN(txt)-spos+1) txt = newtxt spos = STRPOS(txt,'"',spos+1) ENDWHILE txtlines[i] = txt ENDFOR END ;---------------------------------------------------------------------------- PRO mhh_grab_hdr,name,dict,infile_indx,libfile_indx,txt_file,verbose,$ strict ; ; Searches an input file for all text between the ;+ and ;- comments, and ; updates the scratch text file appropriately. Note that this routine ; will extract multiple comment blocks from a single source file if they are ; present. ; ; entry: ; name - Name of file containing documentation header(s). ; dict[] - Dictionary entries for each documentation block in the .PRO ; file. Each dictionary entry is a structure with an index to ; the source filename, an index to the extracted library ; filename (useful only for VMS text libraries), a subject name, ; scratch file offset, unique id (for duplicate names), and ; number of lines of documentation text. ; This parameter may be originally undefined at entry. ; infile_indx - Index of the source .pro or .tlb filename. ; libfile_indx - Index of extracted library filename. If the source ; filename was not a VMS text library, this value should be ; set to -1L. ; txt_file - Scratch file to which the documentation header will ; be written. ; verbose - TRUE if the routine should output a descriptive message ; when it finds the documentation header. ; strict - If nonzero, the routine will adhere strictly to HTML format. ; The document headers will be scanned for characters that are ; reserved in HTML (<,>,&,"), which are then converted to the ; appropriate HTML syntax in the output file. ; ; exit: ; txt_file - Updated as necessary. Positioned at EOF. ; dict[] - Updated array of new dictionary entries. ; COMPILE_OPT hidden ; Under DOS, formatted output ends up with a carriage return linefeed ; pair at the end of every record. The resulting file would not be ; compatible with Unix. Therefore, we use unformatted output, and ; explicity add the linefeed, which has ASCII value 10. LF=10B IF (libfile_indx NE -1L) THEN $ OPENR, in_file, /GET, FILEPATH('mymkhtmlhelp.scr',/TMP), /DELETE $ ELSE $ OPENR, in_file, /GET, name IF (verbose NE 0) THEN MESSAGE,/INFO, 'File = '+name WHILE (1) DO BEGIN ; Find the opening line of the next header. tmp = '' found = 0 num = 0 header = '' ON_IOERROR, DONE WHILE (NOT found) DO BEGIN READF, in_file, tmp IF (STRMID(tmp,0,2) EQ ';+') THEN found = 1 ENDWHILE IF (found) THEN BEGIN ; Find the matching closing line of the header. found = 0 WHILE (NOT found) DO BEGIN READF,in_file,tmp IF (STRMID(tmp,0,2) EQ ';-') THEN BEGIN found =1 ENDIF ELSE BEGIN tmp = strmid(tmp, 1, 1000) header = [header, tmp] num = num + 1 ENDELSE ENDWHILE IF (strict) THEN mhh_strict,header ; Done with one block of header ; Keep track of current scratch file offset, then write doc text. POINT_LUN,-txt_file,pos FOR i=1, num DO BEGIN WRITEU, txt_file, header[i],LF ENDFOR ; Search for the subject. It is the line following name. index = WHERE(STRTRIM(header, 2) EQ 'NAME:', count) IF (count eq 1) THEN BEGIN sub = STRUPCASE(STRTRIM(header[index[0]+1], 2)) IF (verbose NE 0) THEN MESSAGE,/INFO, 'Routine = '+sub ; If the NAME field was not present, set the subject to the name of the ; source text file. ENDIF ELSE BEGIN MESSAGE,/INFO,'Properly formatted NAME entry not found...' ifname = name CASE !VERSION.OS_FAMILY OF 'Windows': tok = '\' 'MacOS': tok = ':' ELSE: tok = '/' ENDCASE ; Cut the path. sp0 = 0 spos = STRPOS(ifname,tok,sp0) WHILE (spos NE -1) DO BEGIN sp0 = spos+1 spos = STRPOS(ifname,tok,sp0) ENDWHILE ifname = STRMID(ifname,sp0,(STRLEN(ifname)-sp0)) ; Cut the suffix. spos = STRPOS(ifname,'.') IF (spos NE -1) THEN ifname = STRMID(ifname,0,spos[0]) IF (strict) THEN mhh_strict, ifname sub = STRUPCASE(ifname) MESSAGE,/INFO,' Setting subject to filename: '+sub+'.' ENDELSE ; Calculate unique id in case of duplicate subject names. IF (N_ELEMENTS(dict) EQ 0) THEN $ ndup=0 $ ELSE BEGIN dpos = WHERE(dict.subject EQ sub,ndup) IF (ndup EQ 1) THEN dict[dpos[0]].id = 1 IF (ndup GE 1) THEN ndup = ndup + 1 ENDELSE ; Create a dictionary entry for the document header. entry = {DICT_STR,subject:sub,indx:infile_indx,lib:libfile_indx,$ id:ndup,offset:pos,nline:num} IF (N_ELEMENTS(dict) EQ 0) THEN dict = [entry] ELSE dict = [dict,entry] ENDIF ENDWHILE DONE: ON_IOERROR, NULL FREE_LUN, in_file END ;---------------------------------------------------------------------------- PRO mhh_gen_file,dict,txt_file,infiles,libfiles,outfile,verbose,title,strict ; ; Build a .HTML file with the constituent parts. ; ; entry: ; dict - Array of dictionary entries. Each entry is a structure ; with a subject name, scratch file offset, number of lines ; of documentation text, etc. ; infiles - String array containing the name(s) of .pro or .tlb files ; for which help is being generated. ; libfiles - String array containing the name(s) of .pro files extracted ; from any .tlb files in the infiles array. ; txt_file - Scratch file containing the documentation text. ; outfile - NAME of final HELP file to be generated. ; verbose - TRUE if the routine should output a descriptive message ; when it finds the documentation header. ; title - Scalar string containing the name to go at the top of the ; HTML help page. ; strict - If nonzero, the routine will adhere strictly to HTML format. ; The document headers will be scanned for characters that are ; reserved in HTML (<,>,&,"), which are then converted to the ; appropriate HTML syntax in the output file. ; ; exit: ; outfile has been created. ; txt_file has been closed via FREE_LUN. ; COMPILE_OPT hidden ; Append unique numbers to any duplicate subject names. dpos = WHERE(dict.id GT 0,ndup) FOR i=0,ndup-1 DO BEGIN entry = dict[dpos[i]] dict[dpos[i]].subject = entry.subject+'['+STRTRIM(STRING(entry.id),2)+']' ENDFOR ; Sort the subjects alphabetically. count = N_ELEMENTS(dict) indices = SORT(dict.subject) ; Open the final file. OPENW,final_file,outfile,/STREAM,/GET_LUN IF (verbose NE 0) THEN MESSAGE,/INFO,'Building '+outfile+'...' ; Print a comment indicating how the file was generated. PRINTF,final_file,'' ; Header stuff. PRINTF,final_file,'' PRINTF,final_file,' ' ; Title. PRINTF,final_file,'
' PRINTF,final_file,''
PRINTF,final_file,'Please find below automatically-generated documentation for "some" IDL software.
'
PRINTF,final_file,'This "index" file is (hopefully correctly;-) hyperlinked to IDL source code.
'
PRINTF,final_file,'
'
PRINTF,final_file,'Created by my_mk_html_help, which you can download as part of myidllib
'
PRINTF,final_file,'
'
PRINTF,final_file,'Mattia Vaccari
'
PRINTF,final_file,'
'
; PRINTF,final_file,'This page was created by my routine'
; PRINTF,final_file,'my_mk_html_help. For more information '
; PRINTF,final_file,'on this routine, refer to the IDL Online Help Navigator '
; PRINTF,final_file,'or type:
' ; PRINTF,final_file,'
? my_mk_html_help
' ; PRINTF,final_file,'at the IDL command line prompt.
'
PRINTF,final_file,'Last modified : ',SYSTIME(),'.
'
PRINTF,final_file,'
' PRINTF,final_file,' ' PRINTF,final_file,'
'
tmp = ''
POINT_LUN,txt_file,entry.offset
FOR j=1,entry.nline DO BEGIN
READF,txt_file,tmp
PRINTF,final_file,tmp
ENDFOR
PRINTF,final_file,'' IF (entry.lib NE -1L) THEN BEGIN fname = libfiles[entry.lib] lname = infiles[entry.indx] IF (strict) THEN BEGIN mhh_strict,fname mhh_strict,lname ENDIF ; PRINTF,final_file,'(See '+fname+' in '+lname+')
' PRINTF,final_file,'(See '+fname+' in ../'+lname+')
' ENDIF ELSE BEGIN fname = infiles[entry.indx] IF (strict) THEN mhh_strict,fname ; PRINTF,final_file,'(See '+fname+')
' PRINTF,final_file,'(See '+fname+')
' ENDELSE PRINTF,final_file,'