diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/system/help/xhelp | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'pkg/system/help/xhelp')
-rw-r--r-- | pkg/system/help/xhelp/help.gui | 3027 | ||||
-rw-r--r-- | pkg/system/help/xhelp/mkpkg | 28 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhcmds.x | 185 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhdir.x | 567 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhelp.h | 89 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhelp.x | 167 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhfiles.x | 89 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhhelp.x | 276 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhinit.x | 77 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhofile.x | 188 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhpkg.x | 192 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhprint.x | 151 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhqref.x | 250 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhroot.x | 73 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhsave.x | 184 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhsearch.x | 185 | ||||
-rw-r--r-- | pkg/system/help/xhelp/xhsort.x | 223 | ||||
-rw-r--r-- | pkg/system/help/xhelp/zzdebug.x | 59 |
18 files changed, 6010 insertions, 0 deletions
diff --git a/pkg/system/help/xhelp/help.gui b/pkg/system/help/xhelp/help.gui new file mode 100644 index 00000000..b3f21c07 --- /dev/null +++ b/pkg/system/help/xhelp/help.gui @@ -0,0 +1,3027 @@ +# XHELP.GUI -- Graphics user interface for the IRAF help browser. + +reset-server +appInitialize xhelp XHelp { + +XHelp*objects:\ + toplevel Layout helpLayout\ + helpLayout Group menubarGroup\ + helpLayout Paned helpPanes\ + menubarGroup Layout menubarLayout\ + menubarLayout MenuButton fileButton\ + menubarLayout MenuButton optionsButton\ + menubarLayout Command printButton\ + menubarLayout Command findButton\ + menubarLayout Command searchButton\ + menubarLayout MenuButton historyButton\ + menubarLayout Command helpButton\ + menubarLayout Command quitButton\ +\ + helpPanes Group topicGroup\ + topicGroup Layout topicLayout\ + topicLayout Label topicLabel\ + topicLayout Command reloadButton\ + topicLayout Frame topicFrame\ + topicFrame AsciiText topicEntry\ + topicLayout Command topicClear\ + topicLayout Frame listFrame\ + listFrame Viewport listView\ + listView List topicList\ +\ + helpPanes Group outputGroup\ + outputGroup Layout outputLayout\ + outputLayout Command htbButton\ + outputLayout Command htfButton\ + outputLayout Command htuButton\ + outputLayout Command hthButton\ + outputLayout MenuButton secButton\ + outputLayout MenuButton parButton\ + outputLayout TextToggle hlpOpt\ + outputLayout TextToggle srcOpt\ + outputLayout TextToggle sysOpt\ + outputLayout TextToggle filOpt\ + outputLayout Frame helpFrame\ + helpFrame HTML helpText\ +\ +\ + toplevel TopLevelShell printShell\ + printShell Layout prntLayout\ + prntLayout Group printGroup\ + prntLayout Group printCmdGroup\ +\ + printGroup Layout printLayout\ + printLayout Label toLabel\ + printLayout TextToggle toPrinter\ + printLayout TextToggle toFile\ + printLayout Label printLabel\ + printLayout Frame printFrame\ + printFrame AsciiText printEntry\ + printLayout Label pageLabel\ + printLayout TextToggle pageLetter\ + printLayout TextToggle pageLegal\ + printLayout TextToggle pageA4\ + printLayout TextToggle pageB5\ +\ + printCmdGroup Layout printCmdLayout\ + printCmdLayout Command printOkay\ + printCmdLayout Command printDismiss\ +\ +\ + toplevel TopLevelShell searchShell\ + searchShell Group searchGroup\ + searchGroup Layout searchLayout\ + searchLayout Label resLabel\ + searchLayout Frame resFrame\ + resFrame HTML resList\ + searchLayout Label searchLabel\ + searchLayout Frame searchFrame\ + searchFrame AsciiText searchEntry\ + searchLayout Command searchClear\ + searchLayout Command searchOkay\ + searchLayout Label searchStatus\ + searchLayout TextToggle exactMatch\ + searchLayout Command searchHelp\ + searchLayout Command searchDismiss\ +\ +\ + toplevel TransientShell findShell\ + findShell Layout fsLayout\ + fsLayout Group findGroup\ + fsLayout Group findCmdGroup\ +\ + findGroup Layout findLayout\ + findLayout Label findLabel\ + findLayout Frame findFrame\ + findFrame AsciiText findEntry\ + findLayout TextToggle findDir\ + findLayout TextToggle findCase\ +\ + findCmdGroup Layout findCmdLayout\ + findCmdLayout Command findOkay\ + findCmdLayout Command findClear\ + findCmdLayout Command findDismiss\ +\ +\ + toplevel TopLevelShell fileShell\ + fileShell Layout flist\ + flist Group flGroup\ + flGroup Layout flFrame\ + flFrame Label flistLabel\ + flFrame Frame flistFrame\ + flistFrame AsciiText flistText\ + flFrame Label flpkgLabel\ + flFrame Label flpkgVal\ + flFrame Command flDismiss\ +\ +\ + toplevel TopLevelShell fileBrowser\ + fileBrowser Layout fbLayout\ + fbLayout Group fnavGroup\ + fbLayout Group fbCmdGroup\ + fbLayout Parameter directory\ +\ + fnavGroup Layout fnavLayout\ + fnavLayout Command fnavHome\ + fnavLayout Command fnavUp\ + fnavLayout Command fnavRoot\ + fnavLayout Command fnavRescan\ + fnavLayout Label filterLabel\ + fnavLayout Frame filterFrame\ + filterFrame AsciiText filterEntry\ + fnavLayout Command filterClear\ + fnavLayout Group dirGroup\ + dirGroup Frame dirFrame\ + dirFrame Viewport dirView\ + dirView List dirList\ + fnavLayout Group fileGroup\ + fileGroup Frame fgFrame\ + fgFrame Viewport fileView\ + fileView List fileList\ + fnavLayout Label curdirLabel\ + fnavLayout Label curdirVal\ + fnavLayout Label fnameLabel\ + fnavLayout Frame fnameFrame\ + fnameFrame AsciiText fnameEntry\ + fnavLayout Command fnameClear\ +\ + fnavLayout Group fmtGroup\ + fmtGroup Layout fmtLayout\ + fmtLayout Label fmtLabel\ + fmtLayout TextToggle fmtSrc\ + fmtLayout TextToggle fmtText\ + fmtLayout TextToggle fmtHTML\ + fmtLayout TextToggle fmtPS\ + fmtLayout Label owLabel\ + fmtLayout TextToggle overwrite\ +\ + fbCmdGroup Layout fbCmdLayout\ + fbCmdLayout Command fbcOkay\ + fbCmdLayout Command fbcHelp\ + fbCmdLayout Command fbcDismiss\ +\ +\ + toplevel TopLevelShell doc_source\ + doc_source Layout srcLayout\ + srcLayout Frame srcMenuFrame\ + srcMenuFrame Layout srcMenuBar\ + srcMenuBar Command srcDismiss\ + srcLayout Frame srcFrame\ + srcFrame AsciiText srcText\ +\ +\ + toplevel TopLevelShell hlpShell\ + hlpShell Layout hlpLayout\ + hlpLayout Group hlpMenuGroup\ + hlpMenuGroup Layout hlpMenu\ + hlpMenu Command hlpBack\ + hlpMenu Command hlpForward\ + hlpMenu Command hlpHome\ + hlpMenu Command hlpTutorial\ + hlpMenu Command hlpDismiss\ + hlpLayout Frame hlpTextFrame\ + hlpTextFrame HTML hlpText\ + hlpLayout Label hfLabel\ + hlpLayout Frame hfFrame\ + hfFrame AsciiText hfEntry\ + hlpLayout Command hfFind\ + hlpLayout Command hfClear\ + hlpLayout TextToggle hfDir\ + hlpLayout TextToggle hfCase\ + hlpShell Parameter help\ +\ +\ + toplevel TransientShell warning\ + warning Layout warn\ + warn Frame warnFrame\ + warnFrame Layout WFlayout\ + WFlayout Icon warnIcon\ + WFlayout TextBox warnText\ + warn Frame warnBtnFrame\ + warnBtnFrame Command warnDismiss\ +\ +\ + toplevel TopLevelShell tclShell\ + tclShell Layout tclLayout\ + tclLayout Group tclCmdGroup\ + tclCmdGroup Layout tclCmd\ + tclCmd Command tclClear\ + tclCmd Command tclExecute\ + tclCmd Toggle tclLogging\ + tclCmd Command tclDismiss\ + tclLayout Frame tclFrame\ + tclFrame AsciiText tclEntry\ +\ +\ + toplevel Parameter xhelp\ + xhelp Parameter textout\ + xhelp Parameter alert\ + xhelp Parameter apropos\ + xhelp Parameter pkglist\ + xhelp Parameter helpres\ + xhelp Parameter helpfiles\ + xhelp Parameter printer\ + xhelp Parameter curpack\ + xhelp Parameter curtask\ + xhelp Parameter history\ + xhelp Parameter showtype\ + xhelp Parameter type + + + + !------------------------------------------------------- + ! Define some global resources for the main menu panels. + !------------------------------------------------------- + *shadowWidth: 1 + *background: gray75 + *Arrow.width: 16 + *Arrow.height: 25 + *Text*height: 21 + *Command.height: 21 + *Command.highlightThickness: 1 + *Command.internalHeight: 4 + *MenuButton.height: 21 + *MenuButton.highlightThickness: 1 + *Label.borderWidth: 0 + *Label.shadowWidth: 0 + *TextButton.shadowWidth: 0 + *TextButton.highlightThickness: 1 + *TextToggle*borderWidth: 0 + *TextToggle.highlightThickness: 0 + *Toggle.highlightThickness: 1 + *Group.shrinkToFit: True + + *Arrow.foreground: gray72 + *Arrow.background: gray72 + *Text*background: gray72 + *AsciiText*background: gray72 + *TextBox.background: gray72 + *MultiList*background: gray72 + *List*background: gray72 + *Slider2d*thumbColor: gray75 + + + !------------------------------------------------------------- + ! Define resources to take advantage of the 3D scrollbar look. + !------------------------------------------------------------- + *Scrollbar*background: gray75 + *Scrollbar*width: 15 + *Scrollbar*height: 15 + *Scrollbar*shadowWidth: 1 + *Scrollbar*cursorName: top_left_arrow + *Scrollbar*pushThumb: true + + + !---------------------------------------- + ! Menu resources giving a shadow effect. + !---------------------------------------- + *SmeBSB.leftMargin: 10 + *SmeBSB.rightMargin: 5 + *SmeBSB.shadowWidth: 2 + *SmeBSB*background: SteelBlue + *SimpleMenu*background: gray77 + *SimpleMenu.borderWidth: 2 + *SimpleMenu.borderColor: Black + *SimpleMenu.shadowWidth: 2 + *SimpleMenu.line1.foreground: gray51 + *SimpleMenu.line2.foreground: gray91 + *SimpleMenu.line3.foreground: gray51 + *SimpleMenu.line4.foreground: gray91 + *SimpleMenu.line5.foreground: gray51 + *SimpleMenu.line6.foreground: gray91 + *SimpleMenu.line7.foreground: gray51 + *SimpleMenu.line8.foreground: gray91 + *SimpleMenu.line9.foreground: gray51 + *SimpleMenu.line10.foreground: gray91 + *SimpleMenu.line11.foreground: gray51 + *SimpleMenu.line12.foreground: gray91 + *SimpleMenu.line13.foreground: gray51 + *SimpleMenu.line14.foreground: gray91 + *SimpleMenu.line15.foreground: gray51 + *SimpleMenu.line16.foreground: gray91 + *SimpleMenu.line17.foreground: gray51 + *SimpleMenu.line18.foreground: gray91 + *SimpleMenu.line19.foreground: gray51 + *SimpleMenu.line20.foreground: gray91 + *SimpleMenu.line21.foreground: gray51 + *SimpleMenu.line22.foreground: gray91 + *SimpleMenu.line23.foreground: gray51 + *SimpleMenu.line24.foreground: gray91 + *SimpleMenu.line25.foreground: gray51 + *SimpleMenu.line26.foreground: gray91 + *SimpleMenu.line27.foreground: gray51 + *SimpleMenu.line28.foreground: gray91 + *SimpleMenu.line29.foreground: gray51 + *SimpleMenu.line30.foreground: gray91 + + + !---------------------------------------- + ! Define the default fonts to be used. + !---------------------------------------- + *font: -adobe-times-medium-r-normal-*-14-*-*-* + *Command.font: -adobe-times-bold-i-normal-*-12-*-*-* + *MenuButton.font: -adobe-times-bold-i-normal-*-12-*-*-* + *Toggle.font: -adobe-times-bold-i-normal-*-12-*-*-* + *Label.font: -adobe-times-bold-i-normal-*-12-*-*-* + *TextToggle.font: -adobe-times-bold-i-normal-*-12-*-*-* + *Group*SimpleMenu*font: 7x13 + *HTML*SimpleMenu*font: 7x13 + + *HTML.plainFont: -*-fixed-medium-r-*-*-13-*-*-* + *HTML.listingFont: -*-fixed-medium-r-*-*-13-*-*-* + *HTML.font: -adobe-times-medium-r-normal-*-14-*-*-* + *HTML.boldFont: -adobe-times-bold-r-normal-*-14-*-*-* + *HTML.plainboldFont: -adobe-times-bold-r-normal-*-14-*-*-* + *HTML.fixedboldFont: -adobe-times-bold-r-normal-*-14-*-*-* + *HTML.header1Font: -adobe-times-bold-r-normal-*-18-*-*-* + *HTML.header2Font: -adobe-times-bold-r-normal-*-14-*-*-* + *HTML.header3Font: -adobe-times-bold-r-normal-*-14-*-*-* + *HTML.header4Font: -adobe-times-bold-r-normal-*-14-*-*-* + *HTML.header5Font: -adobe-times-medium-i-normal-*-12-*-*-* + *HTML.header6Font: -adobe-times-bold-r-normal-*-10-*-*-* + *HTML.anchorUnderlines: 0 + *HTML.visitedAnchorUnderlines: 0 + *HTML.anchorColor: blue + *HTML.visitedAnchorColor: red3 + *HTML*background: gray72 + *HTML*Scrollbar.background: gray75 + *HTML*Scrollbar*width: 15 + *HTML*Scrollbar*height: 15 + + + !--------------------------- + ! Set the default resources. + !--------------------------- + *xhelp.title: IRAF Help Browser V1.0 - DEV + *xhelp.geometry: +0+0 + *xhelp.width: 625 + *xhelp.minWidth: 580 + *xhelp.minheight: 450 + *xhelp.height: 850 + + *helpLayout.geometry: 600x700+0+0 + *helpLayout*borderWidth: 0 + *helpLayout*Group.shrinkToFit: True + *helpLayout*Frame.frameType: sunken + *helpLayout*Frame.frameWidth: 1 + *helpLayout*Command.internalHeight: 2 + *helpLayout*MenuButton.internalHeight: 2 + *helpLayout*Label*highlightThickness: 0 + *helpLayout*List*shadeSurplus: False + *helpLayout*List.internalWidth: 10 + *helpLayout*Viewport.allowVert: True + *helpLayout*Viewport.forceBars: True + *helpLayout.width: 600 + *helpLayout.layout: vertical { \ + menubarGroup < +inf -inf * > \ + -1 \ + horizontal { \ + -1 \ + helpPanes < +inf -inf * +inf -inf > \ + -1 \ + } \ + -1 \ + } + *helpLayout*SimpleMenu.shadowWidth: 2 + *helpLayout*SimpleMenu.borderColor: Black + *helpLayout*SimpleMenu.borderWidth: 2 + + *menubarGroup.label: + *menubarGroup.outerOffset: 0 + *menubarGroup.innerOffset: 5 + *menubarGroup.frameType: raised + *menubarGroup.frameWidth: 2 + *menubarGroup*Command.shadowWidth: 0 + *menubarGroup*MenuButton.shadowWidth: 0 + *menubarLayout.layout: horizontal { \ + fileButton 5 \ + optionsButton 5 \ + printButton 5 \ + findButton 5 \ + searchButton 5 \ + historyButton 5 \ + 10 < +inf -inf > \ + helpButton 5 \ + quitButton \ + } + *fileButton.label: File + *fileButton.menuName: fileMenu + *optionsButton.label: Options + *optionsButton.menuName: optsMenu + *printButton.label: Print + *findButton.label: Find + *searchButton.label: Search + *historyButton.label: History + *historyButton.menuName: historyMenu + *helpButton.label: Help + *quitButton.label: Quit + + *topicGroup.label: + *topicGroup.outerOffset: 2 + *topicGroup.innerOffset: 2 + *topicGroup*frameType: chiseled + *topicGroup.frameWidth: 2 + *topicGroup*Label.shadowWidth: 0 + *topicGroup*Label.borderWidth: 1 + *topicGroup*Label.highlightThickness: 1 + *topicGroup*Viewport.useRight: True + *topicGroup*Viewport.useBottom: True + *topicLayout.layout: vertical { \ + 2 < +2 -2 > \ + horizontal { \ + 3 < +3 -3 > \ + topicLabel 2 topicFrame < +inf * > \ + 2 \ + topicClear 5 reloadButton \ + 1 \ + } \ + 4 \ + horizontal { \ + vertical { \ + -1 \ + listFrame < +inf -inf * +inf -inf > \ + -1 \ + } \ + } \ + 2 < +2 -2 > \ + } + *reloadButton.label: Reload + *topicLabel.label: Topic: + *topicLabel.justify: right + *topicEntry*width: 100 + *topicEntry*editType: edit + *topicEntry*font: 7x13 + *topicEntry*displayCaret: True + *topicClear.label: Clear + + *topicList.font: 7x13 + *topicList.width: 500 + *topicList.height: 100 + *topicList.columnSpacing: 20 + *topicList.verticalList: True + !*topicList.defaultColumns: 6 + !*topicList.forceColumns: True + + *outputGroup.label: + *outputGroup.outerOffset: 2 + *outputGroup.innerOffset: 2 + *outputGroup*frameType: chiseled + *outputGroup.frameWidth: 2 + *outputGrout*TextToggle*on: 0 + *outputGroup*TextToggle.frameWidth: 2 + *outputGroup*TextToggle.frameType: chiseled + *outputGroup*TextToggle.location: 0 0 65 25 + *outputGroup*TextToggle.leftMargin: 4 + *outputLayout.layout: vertical { \ + 2 \ + horizontal { \ + 5 \ + htbButton 2 htfButton 2 htuButton 2 hthButton 2 \ + 10 < +inf -10 > \ + secButton 2 parButton \ + 10 < +inf -10 > \ + hlpOpt -2 srcOpt -2 sysOpt 4 filOpt \ + 5 \ + } \ + 2 \ + horizontal { \ + 2 \ + helpFrame < +inf -inf * +inf -inf > \ + 2 \ + } \ + } + *htbButton.label: Back + *htbButton.sensitive: False + *htfButton.label: Forward + *htfButton.sensitive: False + *htuButton.label: Up + *htuButton.sensitive: False + *hthButton.label: Home + *printButton.label: Print + *secButton.label: Sections + *secButton.menuName: secMenu + *parButton.label: Parameters + *parButton.menuName: parMenu + *hlpOpt*label: Help + *hlpOpt*on: 1 + *hlpOpt*onIcon: diamond1s + *hlpOpt*offIcon: diamond0s + *hlpOpt*highlightColor: green + *srcOpt*label: Source + *srcOpt*on: 0 + *srcOpt*onIcon: diamond1s + *srcOpt*offIcon: diamond0s + *srcOpt*highlightColor: green + *sysOpt*label: Sysdoc + *sysOpt*on: 0 + *sysOpt*onIcon: diamond1s + *sysOpt*offIcon: diamond0s + *sysOpt*highlightColor: green + *filOpt*label: Files + *filOpt*on: 0 + *filOpt*onIcon: square1s + *filOpt*offIcon: square0s + *filOpt*highlightColor: yellow + + *helpText.width: 650 + *helpText.height: 620 + *helpText.anchorUnderlines: 1 + *helpText.visitedAnchorUnderlines: 1 + *helpText.verticalScrollOnRight: true + *helpText.translations: \ + <Btn2Down>: popup(secMenu) \n\ + <Btn2Up>: popdown(secMenu) \n\ + <Btn3Down>: popup(navMenu) \n\ + <Btn3Up>: popdown(navMenu) \n + + *helpText*navMenu.foreground: Black + *helpText*navMenu.background: gray75 + *helpText*secMenu.foreground: Black + *helpText*secMenu.background: gray75 + + + !--------------------------+ + ! Printer Shell resources. | + !--------------------------+ + *printShell.title: Printer Selection + *printShell.width: 300 + *printShell.height: 177 + *printShell.minHeight: 177 + *printShell.maxHeight: 177 + *printShell*borderWidth: 0 + *printShell*Group.frameType: chiseled + *printShell*Group.frameWidth: 2 + *printShell*Group.innerOffset: 5 + *printShell*Group.outerOffset: 2 + *printShell*Command.internalheight: 4 + *printShell*Text*editType: edit + *printShell*Text*height: 25 + *printShell*TextToggle.frameWidth: 0 + *printShell*Group.label: + *prntLayout.layout: vertical { \ + printGroup < +inf -inf * > \ + printCmdGroup < +inf -inf * > \ + } + + *printLayout*location: 0 0 70 25 + *printLayout*offIcon: diamond0s + *printLayout*onIcon: diamond1s + *printLayout*highlightColor: yellow + *printLayout*Label.height: 35 + *printLayout*Label.justify: right + *printLayout*TextToggle.frameWidth: 0 + *printLayout*TextToggle.leftMargin: 8 + *printLayout*TextToggle*highlightColor: yellow + *printLayout*TextToggle*onIcon: square1s + *printLayout*TextToggle*offIcon: square0s + *printLayout*TextToggle*alignment: left + *printLayout.layout: vertical { \ + 0 < +0 >\ + horizontal { toLabel 10 toPrinter 10 toFile 10 } \ + 5 < +inf -5 > \ + horizontal { \ + printLabel 5 printFrame < +inf -inf * > -1 \ + } \ + 5 < +inf -5 > \ + horizontal { \ + vertical { pageLabel 10 } \ + 12 \ + horizontal { \ + vertical { pageLetter -3 pageLegal } \ + 10 \ + vertical { pageA4 -3 pageB5 } \ + } \ + } \ + 0 < +0 >\ + } + *toLabel.label: Print to: + *toPrinter.label: Printer + *toPrinter.on: True + *toFile.label: File + *printLabel.label: Printer: + *printFrame.frameType: sunken + *printFrame.frameWidth: 1 + *printEntry*string: printer + *pageLabel.label: Page Size: + *pageLetter.label: Letter + *pageLetter.on: 1 + *pageLegal.label: Legal + *pageA4.label: A4 + *pageB5.label: B5 + + *printCmdLayout.layout: horizontal { \ + 3 \ + printOkay 20 < +inf -20 > printDismiss \ + 3 \ + } + *printOkay.label: Print + *printDismiss.label: Dismiss + + + !-------------------------+ + ! File Browser resources. | + !-------------------------+ + *fileBrowser.width: 450 + *fileBrowser.height: 375 + *fileBrowser.title: Open a New File... + *fileBrowser*borderWidth: 0 + *fileBrowser*Group.frameType: chiseled + *fileBrowser*Group.frameWidth: 2 + *fileBrowser*Group.innerOffset: 3 + *fileBrowser*Group.outerOffset: 3 + *fileBrowser*Group.label: + + *fbLayout.layout: vertical { \ + 2 \ + fnavGroup < +inf -inf * +inf -inf > \ + -2 \ + horizontal { \ + -5 \ + fbCmdGroup < +inf -inf * > \ + -5 } \ + -3 \ + } + + *fnavGroup*Frame.frameType: sunken + *fnavGroup*Frame.frameWidth: 1 + *fnavGroup*Text*editType: edit + *fnavGroup*Text*height: 25 + *fnavGroup*Text*font: 7x13 + *fnavGroup*List.verticalList: True + *fnavGroup*List.defaultColumns: 1 + *fnavGroup*List.forceColumns: True + *fnavGroup*List.font: 7x13 + *fnavGroup*Label.justify: left + *fnavGroup*Viewport.allowVert: True + *fnavGroup*Viewport.allowHoriz: False + *fnavGroup*Viewport.forceBars: True + *fnavGroup*Viewport.useRight: True + *fnavGroup*Group.outerOffset: 7 + *fnavGroup*Group.innerOffset: 3 + *fnavLayout.layout: vertical { \ + 5 \ + vertical { \ + -1 \ + horizontal { \ + 5 \ + fnavHome < +inf -inf * > 2 \ + fnavUp < +inf -inf * > 2 \ + fnavRoot < +inf -inf * > 2 \ + fnavRescan < +inf -inf * > \ + 10 \ + filterLabel 2 filterFrame < +inf -inf * > \ + 2 \ + filterClear \ + 5 \ + } \ + 3 \ + } \ + 5 \ + horizontal { \ + -5 \ + dirGroup < +inf -inf * +inf - inf > \ + -8 \ + fileGroup < +inf -inf * +inf - inf > \ + -5 \ + } \ + -3 \ + horizontal { \ + curdirLabel 5 curdirVal < +inf -inf * > 5 } \ + 5 \ + horizontal { \ + fnameLabel 2 fnameFrame < +inf -inf * > 2 fnameClear 5\ + } \ + 7 \ + fmtGroup < +inf -inf * > \ + -3 \ + } + *fileBrowser*fnavGroup*dirGroup.label: Directories + *fileBrowser*fnavGroup*fileGroup.label: Files + *fileBrowser*fnavGroup*dirGroup.innerOffset: 3 + *fileBrowser*fnavGroup*fileGroup.innerOffset: 3 + *fileBrowser*fnavGroup*dirGroup.outerOffset: 7 + *fileBrowser*fnavGroup*fileGroup.outerOffset: 7 + *fileBrowser*fnavGroup*dirGroup.font: 7x13bold + *fileBrowser*fnavGroup*fileGroup.font: 7x13bold + + *filterLabel.label: Filter + *filterClear.label: Clear + *curdirLabel.label: Directory: + *curdirVal.label: + *curdirVal.font: 7x13 + *fnameLabel.label: Selection\ \ + *fnameClear.label: Clear + *fnavHome.label: Home + *fnavUp.label: Up + *fnavRoot.label: Root + *fnavRescan.label: Rescan + + *fmtGroup*Group.outerOffset: 3 + *fmtGroup*Group.innerOffset: 3 + *fmtLayout*TextToggle.frameWidth: 0 + *fmtLayout*TextToggle.leftMargin: 4 + *fmtLayout*TextToggle.alignment: left + *fmtLayout*TextToggle*highlightColor: yellow + *fmtLayout*TextToggle*onIcon: square1s + *fmtLayout*TextToggle*offIcon: square0s + *fmtLayout.layout: vertical { \ + horizontal { 5 fmtLabel 10 fmtSrc 3 fmtText 3 fmtHTML 3 fmtPS 5 } \ + horizontal { 50 owLabel 10 overwrite 5 < +inf > } \ + } + *fmtLabel.label: Save As Format: + *fmtSrc.label: Source + *fmtSrc.on: 1 + *fmtSrc.location: 0 0 65 22 + *fmtText.label: Text + *fmtText.location: 0 0 65 22 + *fmtHTML.label: HTML + *fmtHTML.location: 0 0 65 22 + *fmtPS.label: PostScript + *fmtPS.location: 0 0 100 22 + *owLabel.label: Options: + *overwrite.label: Allow overwrite of existing files? + *overwrite.location: 0 0 200 22 + + *fbCmdLayout.outerOffset: 0 + *fbCmdLayout.layout: horizontal { \ + 5 \ + vertical { 2 fbcOkay 2 } \ + 20 < +inf -20 > \ + vertical { 2 fbcHelp 2 } \ + 2 \ + vertical { 2 fbcDismiss 2 } \ + 5 \ + } + *fbcOkay.label: Okay + *fbcHelp.label: Help + *fbcDismiss.label: Dismiss + + + !-----------------------+ + ! Find Shell resources. | + !-----------------------+ + *findShell.title: Find within a document... + *findShell.width: 365 + *findShell.height: 130 + *findShell*borderWidth: 0 + *findShell*Group.frameType: chiseled + *findShell*Group.frameWidth: 2 + *findShell*Group.innerOffset: 5 + *findShell*Group.outerOffset: 2 + *findShell*Command.internalheight: 4 + *findShell*Text*editType: edit + *findShell*Text*height: 25 + *findShell*TextToggle.frameWidth: 0 + *findShell*Group.label: + *fsLayout.layout: vertical { \ + findGroup < +inf -inf * > \ + findCmdGroup < +inf -inf * > \ + } + + *findLayout*location: 0 0 120 25 + *findLayout*offIcon: diamond0s + *findLayout*onIcon: diamond1s + *findLayout*highlightColor: yellow + *findLayout*Label.height: 35 + *findLayout*Label.justify: right + *findLayout*TextToggle.frameWidth: 0 + *findLayout*TextToggle.leftMargin: 4 + *findLayout*TextToggle*highlightColor: yellow + *findLayout*TextToggle*onIcon: square1s + *findLayout*TextToggle*offIcon: square0s + *findLayout.layout: vertical { \ + 5 \ + horizontal { \ + findLabel 7 findFrame < +inf -inf * > -1 \ + } \ + 5 \ + horizontal { \ + 20 < +inf -20 > \ + findDir 10 findCase \ + 20 < +inf -20 > \ + } \ + } + *findLabel.label: Find: + *findFrame.frameType: sunken + *findFrame.frameWidth: 1 + *findEntry*string: + *findDir.label: Find Backwards + *findCase.label: Case Sensitive + + *findCmdLayout.layout: horizontal { \ + 3 \ + findOkay \ + 20 < +inf -20 > \ + findClear \ + 20 < +inf -20 > \ + findDismiss \ + 3 \ + } + *findOkay.label: Find + *findClear.label: Clear + *findDismiss.label: Dismiss + + + !-------------------------------------------+ + ! Set the document source viewer resources. | + !-------------------------------------------+ + *doc_source.title: Page source + *doc_source.width: 575 + *doc_source.height: 450 + *srcLayout*borderWidth: 0 + *srcLayout.layout: vertical { \ + srcMenuFrame < +inf -inf * > \ + -2 \ + srcFrame < +inf -inf * +inf -inf > \ + -2 \ + } + + *srcMenuBar.layout: horizontal { 50 < +inf -inf > srcDismiss 5 } + *srcMenuFrame.height: 40 + *srcMenuFrame.outerOffset: 0 + *srcMenuFrame.innerOffset: 5 + *srcMenuFrame.frameType: chiseled + *srcMenuFrame.frameWidth: 2 + *srcFrame.frameType: sunken + *srcFrame.frameWidth: 1 + *srcFrame.outerOffset: 5 + *srcText*scrollVertical: always + *srcText*scrollHorizontal: always + *srcText*Scrollbar.width: 15 + *srcText*Scrollbar.height: 15 + *srcText*background: gray75 + *srcText*font: 7x13 + *srcText*editType: read + *srcText*displayCaret: False + *srcDismiss.label: Dismiss + *srcDismiss.width: 150 + + + !-------------------------+ + ! Search Shell resources. | + !-------------------------+ + *searchShell.title: Search for a topic... + *searchShell.width: 600 + *searchShell.height: 250 + *searchShell*borderWidth: 0 + *searchShell*Viewport.allowVert: True + *searchShell*Viewport.allowHoriz: True + *searchShell*Viewport.useBottom: True + *searchShell*Viewport.useRight: False + *searchShell*Viewport.forceBars: True + *searchGroup.frameType: chiseled + *searchGroup.frameWidth: 2 + *searchGroup.innerOffset: 7 + *searchGroup.outerOffset: 7 + *searchGroup.highlightThickness: 0 + *searchGroup.label: + *searchLayout.layout: vertical { \ + horizontal { \ + 45 < +45 -45 > \ + resLabel < +inf -inf * > \ + 5 < +inf -inf > \ + exactMatch \ + } \ + 2 < +2 - 2 > \ + resFrame < +inf -inf * +inf -inf > \ + 5 < +5 - 5 > \ + horizontal { \ + searchLabel 5 searchFrame \ + 5 \ + searchClear 2 searchOkay \ + 5 < +inf -inf > \ + searchStatus \ + 5 < +inf -inf > \ + searchHelp 2 searchDismiss \ + } \ + } + *resLabel.label: Task Package Description + *resLabel.justify: left + *resFrame.frameType: sunken + *resFrame.frameWidth: 1 + *resList.font: 7x13 + *resList.width: 100 + *resList.height: 100 + *resList.marginWidth: 5 + *resList.marginHeight: 5 + + *searchLabel.label: Topic: + *searchFrame.frameType: sunken + *searchFrame.frameWidth: 1 + *searchEntry*font: 7x13 + *searchEntry*displayCaret: True + *searchEntry*editType: edit + *searchEntry*height: 25 + *searchEntry*width: 150 + *searchClear.label: Clear + *searchOkay.label: Search + *searchStatus.label: + *exactMatch.label: Require Exact Match + *exactMatch*on: 1 + *exactMatch*onIcon: diamond1s + *exactMatch*offIcon: diamond0s + *exactMatch*highlightColor: green + *exactMatch.frameWidth: 2 + *exactMatch.frameType: chiseled + *exactMatch.location: 0 0 150 25 + *exactMatch.leftMargin: 4 + *searchHelp.label: Help + *searchDismiss.label: Dismiss + + + !---------------- + ! Help Window. + !---------------- + *hlpShell.title: Help + *hlpShell.width: 500 + *hlpShell.height: 620 + *hlpLayout*borderWidth: 0 + *hlpLayout*Frame*frameType: sunken + *hlpLayout*Frame*frameWidth: 1 + + *hlpMenuGroup.label: + *hlpMenuGroup.outerOffset: 0 + *hlpMenuGroup.innerOffset: 0 + *hlpLayout.layout: vertical { \ + hlpMenuGroup < +inf -inf * > \ + -3 \ + hlpTextFrame < +inf -inf * +inf -inf > \ + horizontal { \ + 5 \ + hfLabel 5 hfFrame < +inf -inf *> \ + 2 \ + hfFind 2 hfClear 5 hfDir 5 hfCase \ + 5 \ + } \ + 2 \ + } + *hlpLayout*TextToggle*location: 0 0 90 25 + *hlpLayout*TextToggle*offIcon: diamond0s + *hlpLayout*TextToggle*onIcon: diamond1s + *hlpLayout*TextToggle*highlightColor: yellow + *hlpLayout*TextToggle*frameType: chiseled + *hlpLayout*TextToggle*frameWidth: 2 + *hfEntry*editType: edit + *hfEntry*font: 7x13 + *hfEntry*displayCaret: True + *hfLabel.label: Find: + *hfFind.label: Find + *hfClear.label: Clear + *hfDir.label: Backwards + *hfCase.label: Caseless + *hfCase.on: true + + *hlpMenu*Command.internalHeight: 4 + *hlpMenu*Command.highlightThickness: 1 + *hlpMenu*Command.height: 20 + *hlpMenu.layout: vertical { \ + 5 \ + horizontal { \ + 5 \ + hlpBack 2 hlpForward 2 hlpHome 2 hlpTutorial \ + 20 < +inf -20 > \ + hlpDismiss \ + 5 \ + } \ + 5 \ + } + *hlpBack.label: Back + *hlpBack.sensitive: False + *hlpForward.label: Forward + *hlpHome.label: Home + *hlpTutorial.label: Tutorial + *hlpTutorial.sensitive: false + *hlpDismiss.label: Dismiss + + *hlpTextFrame.outerOffset: 2 + *hlpText.width: 500 + *hlpText.height: 500 + *hlpText.anchorUnderlines: 1 + *hlpText.visitedAnchorUnderlines: 1 + *hlpText.verticalScrollOnRight: true + + + !------------------+ + ! File List dialog. + !------------------+ + *fileShell.title: Help Files + *fileShell.geometry: 500x165 + *fileShell*borderWidth: 0 + *fileShell*Command.width: 90 + *fileShell*Command.height: 30 + *fileShell*Frame.frameType: sunken + *fileShell*Frame.frameWidth: 1 + *fileShell*Frame.innerOffset: 1 + *fileShell*Text*font: 7x13 + *flist.layout: vertical { \ + 1 \ + horizontal { 1 flGroup < +inf -inf * +inf -inf> 1 } \ + 1 \ + } + + *flGroup.frameType: chiseled + *flGroup.frameWidth: 2 + *flGroup.innerOffset: 5 + *flGroup.outerOffset: 5 + *flGroup.label: + *flFrame.layout: vertical { \ + 5 \ + horizontal { \ + 13 \ + flistLabel < +inf -inf * > \ + 5 < +inf -5 > \ + } \ + 2 \ + horizontal { 1 flistFrame < +inf -inf * +inf -inf > 1 } \ + 7 \ + horizontal { \ + 5 \ + flpkgLabel 2 flpkgVal < +inf -inf * > \ + 5 < +inf -5 > \ + flDismiss \ + 5 \ + } \ + } + *flDismiss.label: Dismiss + *flistLabel.label: Option Status Filename + *flistLabel.justify: left + *flpkgLabel.label: Task: + *flpkgLabel.justify: left + *flpkgVal.label: (Undefined) + *flpkgVal.justify: left + *flpkgVal*font: 7x13 + *flistText.label: + *flistText.scrollVertical: Never + *flistText.scrollHorizontal: whenNeeded + *flistText*displayCaret: False + *flistText*editType: edit + + + !----------------+ + ! WARNING dialog. + !----------------+ + *warning.geometry: +400+300 + *warning*borderWidth: 0 + *warning*TextBox.frameWidth: 0 + *warning*Command.width: 90 + *warning*Command.height: 30 + *warning*Frame.frameType: sunken + *warning*Frame.frameWidth: 1 + *warning*Frame.innerOffset: 3 + *warn.layout: vertical { \ + 5 \ + horizontal { \ + 5 \ + warnFrame < +inf * +inf > \ + 5 \ + } \ + 5 \ + horizontal { \ + 5 < +inf -5 > \ + warnBtnFrame \ + 5 < +inf -5 > \ + } \ + 5 \ + } + + *WFlayout.layout: horizontal { \ + 5 \ + vertical { \ + 5 < +inf -5 > \ + warnIcon \ + 5 < +inf -5 > \ + } \ + 5 \ + warnText < +inf -inf * +inf -inf > \ + 5 \ + } + *warnIcon.location: 0 0 40 40 + *warnIcon.image: WARNING + *warnText.label: generic warning text + *warnText.width: 270 + *warnText.height: 60 + *warnText*background: gray75 + *warnDismiss.label: Dismiss + + !-------------------------- + ! Define a Debug Tcl shell. + !-------------------------- + *tclShell.width: 550 + *tclShell.height: 180 + *tclShell.title: TCL Command Entry Shell + *tclLayout*borderWidth: 0 + *tclLayout*Frame.frameType: sunken + *tclLayout*Frame.frameWidth: 1 + *tclLayout.layout: vertical { \ + tclCmdGroup < +inf -inf * > \ + tclFrame < +inf -inf * +inf -inf> \ + } + *tclEntry*editType: edit + *tclEntry*type: string + *tclEntry*scrollVertical: Always + *tclEntry*scrollHorizontal: whenNeeded + + *tclCmdGroup.label: + *tclCmdGroup.outerOffset: 0 + *tclCmdGroup.innerOffset: 0 + *tclCmd.layout: vertical { \ + 5 \ + horizontal { \ + 5 \ + tclClear 3 tclExecute \ + 10 < +inf -10> \ + tclLogging 3 tclDismiss \ + 5 \ + } \ + 5 \ + } + *tclClear.label: Clear + *tclExecute.label: Execute + *tclLogging.label: Enable Logging + *tclDismiss.label: Dismiss +} + + + +################################################################################ + +createObjects + +# Define Bitmaps and Pixmaps to be used. +createBitmap null 16 16 { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + +createBitmap check 16 16 { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, + 0x00, 0x30, 0x00, 0x18, 0x00, 0x0c, 0x08, 0x06, 0x18, 0x03, 0xb0, 0x01, + 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00} + +createBitmap arrow 16 16 { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x14, 0xf8, 0x27, + 0x08, 0x40, 0xf8, 0x27, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + +activate + +################################################################################ + + +################################################################################ +# Global variables. | +################################################################################ +set version "IRAF Help GUI V1.0" ;# version string +set curpack "" ;# current values +set curtask "" +set helpType "package" ;# type of help to get +set helpOption "help" ;# help option param +set fileManaged 0 ;# is fileShell mapped? +set pkgList { } +set visited(0) empty + +set listOrient 1 ;# options +set showType 0 +set showFiles 1 +set exactMatch 1 + +set MAX_MENU_SIZE 40 ;# what it says it is + +# History array initialization. +set HPkg(0) {Home} ;# package +set HOpt(0) {help} ;# option +set HTask(0) {Home} ;# task +set HUrl(0) {} ;# url +set HType(0) {task} ;# type (task|package|file) +set HFile(0) {} ;# filename +set htop 0 ;# top of array +set hcurrent 0 ;# current page + +# Panel mapping flags. +set search_mapped 0 ;# searchShell mapped? + + +################################################################################ +# Utility Callbacks +################################################################################ + +# Procedures for sending client cursor commands. +proc GKey { key args } { send client gkey $key } +proc GCmd { args } { send client gcmd $args } + +# Procedures to test True/False strings in resources. +proc true { v } \ + { expr { $v=="true" || $v=="True" || $v=="TRUE" || $v==1 || $v=="yes" } } +proc false { v } \ + { expr { $v=="false" || $v=="False" || $v=="FALSE" || $v==0 || $v=="no" } } + +# No-op procedure for text widgets with no callbacks to swallow newline. +proc noop { args } { } + +# Common functions. +proc min { a b } { expr {($a < $b) ? $a : $b} } +proc max { a b } { expr {($a > $b) ? $a : $b} } + + +#--------------------+ +# Debugging options. | +#--------------------+ +set debug 0 ;# debug flag +send tclLogging set state [min 1 $debug] + + +################################################################################ +# Initialize. | +################################################################################ +proc Init args { + global history curpack curtask debug + global secMenuDescription parMenuDescription + global HPkg HTask HUrl HOpt HFile HType + + if {$debug == 1} { send tclShell map } + + # Reinitialize global vars in case of a restart. + set curpack "" + set curtask "" + set helpType "package" + set helpOption "help" + + # Initialize the entry strings. + send printEntry set string "" + send topicEntry set string "" + + # Initialize the various lists. + send topicList setList "{ }" resize + + send secButton set sensitive False + send parButton set sensitive False + editMenu secMenu secButton $secMenuDescription + editMenu parMenu parButton $parMenuDescription + +} ; #send server postActivateCallback Init + + + +# Create the Navigation Menu. +set navMenuDescription { + { "Back " f.exec { Back } + sensitive {([send htbButton isSensitive]==1) ? "true" : "false" } + } + { "Forward " f.exec { Forward } + sensitive {([send htfButton isSensitive]==1) ? "true" : "false" } + } + { "Up " f.exec { Up } + sensitive {([send htuButton isSensitive]==1) ? "true" : "false" } + } + { "Home " f.exec { Home } } + { f.dblline } + { "Reload " f.exec { Reload } } + { "Open File... " f.exec { Open } } + { "Save As... " f.exec { SaveAs } } + { "View Page Source " f.exec { srcOpen } } + { f.dblline } + { "Find... " f.exec { Find } } + { "Search... " f.exec { Search } } + { "Print... " f.exec { Print } } +} ; createMenu navMenu helpText $navMenuDescription + +# Create the default Section Menu. +set secMenuDescription { + { " Top of Page " f.exec { send helpText gotoId 0 } } + { f.dblline } + { " " f.exec { noop } } + { " No Sections Found " f.exec { noop } } + { " " f.exec { noop } } +} ; createMenu secMenu secButton $secMenuDescription + +# Create the default Parameter Menu. +set parMenuDescription { + { " No Parameters Found" f.exec { noop } } +} ; createMenu parMenu parButton $parMenuDescription + + +# Initialize. +Init + + +################################################################################ +# Menubar command callbacks. +################################################################################ + +# File Menu +set fileMenuDescription { + { " Open File... " f.exec { Open } } + { " Save As... " f.exec { SaveAs } } + { " Print... " f.exec { Print } } + { f.dblline } + { " Reload... " f.exec { Reload } } + { " View Page Source " f.exec { srcOpen } } + { " Search... " f.exec { Search } } + { " Find... " f.exec { Find } } + { f.dblline } + { " Help " f.exec { Help } } + { " Quit " f.exec { Quit } } +} ; createMenu fileMenu fileButton $fileMenuDescription + + +# History Menu +set historyMenuDescription { + { " Back " f.exec { Back } + sensitive {([send htbButton isSensitive]==1) ? "true" : "false" } + } + { " Forward " f.exec { Forward } + sensitive {([send htfButton isSensitive]==1) ? "true" : "false" } + } + { " Up " f.exec { Up } + sensitive {([send htuButton isSensitive]==1) ? "true" : "false" } + } + { " Home " f.exec { Home } } + { f.dblline } + { " Clear History" f.exec { histClear } } + { f.dblline } +} ; createMenu historyMenu historyButton $historyMenuDescription + + +# Options Menu +set optsMenuDescription { + { " Show task type " f.exec { setOpts showType } + bitmap {($showType==1)? "check" : "null"} } + { " Show missing files " f.exec { setOpts showFiles } + bitmap {($showFiles==1)? "check" : "null"} } + { f.dblline } + { " Vertical task listing " f.exec { setOpts verticalList True } + bitmap {($listOrient==1)? "check" : "null"} + } + { " Horizontal task listing " f.exec { setOpts verticalList False } + bitmap {($listOrient==0)? "check" : "null"} + } + { f.dblline } + { " Tcl Command Shell " f.exec { tclOpen } } +} ; createMenu optsMenu optionsButton $optsMenuDescription + + +proc setOpts { opt args } { + global optsMenuDescription + global listOrient showType showFiles + global HTask HPkg HOpt hcurrent + + switch $opt { + showType { set showType [expr { ($showType == 1) ? 0 : 1 } ] + GCmd type $showType + set h $hcurrent + GCmd help $HTask($h) $HPkg($h) $HOpt($h) + } + showFiles { set showFiles [expr { ($showFiles == 1) ? 0 : 1 } ] + } + verticalList { set listOrient [expr { ($args == "False") ? 0 : 1 } ] + send topicList set verticalList $args + } + } + editMenu optsMenu optionsButton $optsMenuDescription +} + +proc Print args { + send printShell map +} ; send printButton addCallback Print + +proc Find { args } { + send findShell popup +} ; send findButton addCallback Find + +proc Search { args } { + global search_mapped + + send searchShell map + set search_mapped 1 +} ; send searchButton addCallback Search + +proc Reload args { + global HPkg HType HUrl HOpt HTask HFile hcurrent + + if { $HType($hcurrent) == "file"} { + if {[info exists HFile($hcurrent)] == 1} { + GCmd directory open $HFile($hcurrent) + } else { + setAlert param old [format "HFile param at %d not found" $hcurrent] + } + } else { + loadHistItem $hcurrent $HPkg($hcurrent) $HTask($hcurrent) \ + $HOpt($hcurrent) $HType($hcurrent) $HUrl($hcurrent) + } +} ; send reloadButton addCallback Reload + +proc Help args { + send hlpShell map +} ; send helpButton addCallback Help + +proc Open args { + send fmtGroup unmap + send fmtGroup set height 0 + send fbcOkay set label Load + send fileBrowser map +} + +proc SaveAs args { + global format + + # Reset the default format every time we open. + send $format set on 0 + set format fmtSrc + send $format set on 1 + + # If there's no filename specified set one as a default. + setDefaultFname + + send fmtGroup map + send fmtGroup set height 65 + send fbcOkay set label Save + send fileBrowser map +} + +proc Quit args { + GCmd quit + deactivate unmap +}; send quitButton addCallback Quit + + + +################################################################################ +# Callbacks for client state variables (UI parameter objects). When the +# client's state changes it updates a UI parameter to reflect the change. +# This produces a callback to one or more of the callbacks defined below, +# used to update the GUI to reflect the changing state of the client. +################################################################################ + +proc setShowType { param old new } { + global showType listOrient showFiles optsMenuDescription + set showType $new + editMenu optsMenu optionsButton $optsMenuDescription +}; send showtype addCallback setShowType + +proc setTopics { param old new } { + global pkgList + set pkgList $new + send topicList setList $new resize +}; send pkglist addCallback setTopics + +proc appendHist { param old new } { + global helpType helpOption curtask curpack + + if {$new == "package"} { + #addHistRecord $curpack $curpack "" $helpOption "" $helpType + addHistRecord $curpack $curpack "" $helpOption "" "package" + } elseif {$new == "append"} { + # We've got a result of some kind and all of the values have been + # set, so create a history record. + if {$curpack != "" && $curtask != ""} { + addHistRecord $curpack $curtask "" $helpOption "" $helpType + } + } +}; send history addCallback appendHist + +proc setCurpack { param old new } { + global curpack + + if { $new != [getPkgName $curpack] } { + if { $curpack != "" && \ + $curpack != "clpackage" && \ + [string match "root*" $new] != 1} { + set curpack [ format "%s.%s" $curpack $new] + send htuButton set sensitive true + } else { + set curpack $new + } + } +}; send curpack addCallback setCurpack + + +proc setCurtask { param old new } { + global curtask curpack helpType + + if {$helpType == "package"} { + send topicEntry set string $curpack + } else { + send topicEntry set string [ format "%s.%s" $curpack $new ] + } + + # Update the printer dialog so the filename defaults to the curtask. + if { [send toFile get on] } { + if {$HType($hcurrent) == "file" || [send srcOpt get on] == 1} { + send printEntry set string [format "%s" [fileSource] ] + } else { + send printEntry set string [format "%s.ps" $new] + } + } else { + send printEntry set string "printer" + } + set curtask $new +}; send curtask addCallback setCurtask + + +proc getPkgName { pkg } { + set last [ string last "." $pkg ] + if { $last > -1 } { + return [ string range $pkg [incr last] end ] + } else { + return $pkg + } +} + +proc getParentName { pkg } { + set last [ string last "." $pkg ] + if { $last > -1 } { + set root [ string range $pkg 0 [incr last -1] ] + } else { + set root $pkg + } + return [getPkgName $root] +} + + +# Topic list selection callback. +proc topicSelect { widget event args } { + global htop hcurrent curpack curtask helpOption helpType + global visited + + # If we're currently positioned somewhere in the middle of the + # history menu, push the current page to the history list before + # getting the next result. + if {$htop != $hcurrent} { + addHistRecord $curpack $curtask "" $helpOption "" $helpType + send htbButton set sensitive True + send htuButton set sensitive True + } + + set item [string trimright [send topicList getItem itemno] "."] + send topicList getItem itemno + if { $itemno != "none" } { + GCmd help $item $curpack $helpOption + set visited($item) 1 + } +} ; send topicList addEventHandler topicSelect buttonReleaseMask + +proc listViewResize { args } { + global pkglist + send topicList setList $pkglist resize +} ; send listView addEventHandler listViewResize ResizeRedirectMask + + +# Get help for a specific topic from the topic entry widget. +proc getTopicHelp { widget mode topic args } { + global curpack helpOption + + if { [string match "*\.*" $topic] == 1} { + set pkglist [ split $topic "." ] + set pack [lindex $pkglist [expr {[llength $pkglist] - 2}] ] + set task [lindex $pkglist [expr {[llength $pkglist] - 1}] ] + set curpack $pack + GCmd help $task $curpack $helpOption + } else { + set curtask "" + set curpack "" + GCmd help $topic $curpack $helpOption + } +} ; send topicEntry addCallback getTopicHelp + +proc topicClear { args } { + send topicEntry set string "" +} ; send topicClear addCallback topicClear + + + +################################################################################ +# Help text and HTML processing procedures. +################################################################################ + +proc setHelpResult { param old new } { + global helpType helpOption curtask curpack + global secMenuDescription parMenuDescription + global pkgList debug + + # Debug status + if {$debug == 1} { + send tclEntry append \ + [format "helpres: type=%1.1s opt=%4.4s curtask=%s curpack=%s\n" \ + $helpType $helpOption $curtask $curpack ] + print [format "helpres: type=%1.1s opt=%4.4s curtask=%s curpack=%s\n" \ + $helpType $helpOption $curtask $curpack ] + } + + if { [string match "*<HTML>*" $new] == 1} { + # Strip the header table. + if {[ string match "*TABLE*" $new] == 1 } { + set new_start [expr [string first "</TABLE>" $new] + 12] + set text [ filterBraces [string range $new $new_start end] ] + } else { + set text [ filterBraces $new ] + } + + # Got HTML directly from the client. + send helpText setText [format "<HTML><BODY>\n%s" $text ] + + # Save the source for the viewer + set docSrc \ + [ format "<HTML><BODY>\n%s\n</BODY></HTML>\n" $text] + + # Parse the file for menu items. + setSectionMenu $new + setParameterMenu $new + + } else { + # Disable help page content buttons for plain text. + send parButton set sensitive False + send secButton set sensitive False + editMenu secMenu secButton $secMenuDescription + editMenu parMenu parButton $parMenuDescription + + # Filter plaintext .men files into something with links, otherwise + # unescape the curly braces used to pass the text through Tcl. + if {$helpType == "package"} { + set str [ filterLinks [ filterTcl $new ] ] + } else { + set str [ filterTcl $new ] + } + + # Load the results + send helpText setText "<HTML><BODY><PRE>\n$str\n</PRE></BODY></HTML>" + + # Save the source for the viewer + set docSrc \ + [ format "<HTML><BODY><PRE>\n%s\n</PRE></BODY></HTML>\n" $str] + } + send helpText retestAnchors + send srcText set string $docSrc + + # See which files associated with this topic are available. We turn off + # the option toggles first so they can be reset as needed by the client. + if {$helpOption != "sysdoc"} {send sysOpt "set sensitive False ; set on 0" } + if {$helpOption != "source"} {send srcOpt "set sensitive False ; set on 0" } + + if {$helpType == "package"} { + set parent [getParentName $curpack] + if {$parent == "clpackage" || [string match "root*" $parent] == 1} { + GCmd files $curtask "clpackage" + } else { + GCmd files $curtask $parent + } + } else { + GCmd files $curtask [string range $curpack \ + [expr {[string last "." $curpack ] + 1}] end] + } + + # Highlight the package list item. + for {set i 0} {$i < [llength $pkgList]} {incr i} { + if {[lindex $pkgList $i] == $curtask } { + send topicList highlight $i + break + } + } + printHistStack "helpres " + +}; send helpres addCallback setHelpResult + + +# Set an arbitrary TextToggle widget highlight color. +proc setOptColor { widget color args } { + send $widget "set on 1 ; \ + set offIcon diamond0s ; \ + set highlightColor $color ; \ + set background gray75 ; \ + set onIcon diamond1s ; \ + set highlightColor $color ; \ + set background gray75" +} + + +# Set the file options for the files that were found to be valid (i.e. +# they're listed in the files output and actually exist). +proc setHelpFileOpts { param old new } { + global helpType helpOption curtask curpack + global showFiles + + set opt [lindex $new 0] + set val [lindex $new 1] + if {$opt != "file"} { set stat [lindex $new 2] } + + # Set the option toggles according to valid files. + if {$opt == "sys" && $stat == 0} { + send sysOpt set sensitive True + } elseif {$opt == "sys" && $stat == 1 && $showFiles == 1} { + setOptColor sysOpt yellow + } + if {$opt == "src" && $stat == 0} { + send srcOpt set sensitive True + } elseif {$opt == "src" && $stat == 1 && $showFiles == 1} { + setOptColor srcOpt yellow + } + + # Update the help files panel text. + if {$opt == "file"} { + set pkg [ string trimright $val ":"] + send flpkgVal set label [ format "%s" $pkg ] + send toplevel set title [format "XHelp: %s" $pkg ] + send flistText set string "" + } else { + send flistText append [ format " %5.5s %-7.7s %s\n" \ + $opt \ + [ expr { ($stat == 0) ? "Okay" : "Error" }] \ + $val] + } + +} ; send helpfiles addCallback setHelpFileOpts + + +# Process an HREF link selection. URLs are assumed to be of the form +# +# <pkgname>.<task> +# <task> +# '#'<hname> +# +# If an internal link is found as in the last case we ignore any defined +# package/task given, otherwise load the selected page. + +proc textAnchorSelected {widget cbtype event text href args} { + global HPkg HType HUrl HOpt HTask HFile hcurrent htop + global curpack helpOption visited + + set visited($href) 1 + send helpText retestAnchors + + if {[string match "*#*" $href] == 1} { + set link [string range $href [expr [string first "#" $href] + 1] end ] + set HUrl($hcurrent) $link + send helpText gotoId [ send helpText anchorToId $link ] + } else { + if { [string match "*\.*" $href] == 1} { + set pack [lindex [split $href "."] 0] + set task [lindex [split $href "."] 1] + set curpack $pack + GCmd help $task $curpack $helpOption + + } else { + GCmd help $href $curpack $helpOption + } + } + + if {$hcurrent <= $htop} { + set h $hcurrent + addHistRecord $HPkg($h) $HTask($h) $HUrl($h) $HOpt($h) \ + HFile($h) $HType($h) + } + +}; send helpText addCallback textAnchorSelected anchor + + +# Remove only the escaped curly braces. Used to filter HTML text passed to +# the GUI with escapes in it. + +proc filterBraces { istr args } { + if {$istr != ""} { + regsub -all {(\\\{)} $istr "\{" v1 + regsub -all {(\\\})} $v1 "\}" results + return $results + } +} + +# Remove the backslash escapes from source files, escape special chars for +# presentation on an HTML widget. + +proc filterTcl { istr args } { + if {$istr != ""} { + regsub -all {(\\\{)} $istr "\{" v1 + regsub -all {(\\\})} $v1 "\}" v2 + regsub -all {(\<)} $v2 "\\<" v3 + regsub -all {(\>)} $v3 "\\>" results + return $results + } +} + + +# Scan a plaintext doc to see if maybe this is a package help menu. We use +# some assumption that most of the lines will be of the form "task '-' desc" +# then parse the file resetting all of the 'task' names as HREFs for other +# tasks. + +proc filterLinks { istr args } { + + set lines [split $istr "\n"] + set blank " " + set results { } + lappend results "" + foreach i $lines { + set line [string trimleft [detab $i] ] + if {[regexp {(^[a-zA-Z0-9\ \_\(\)]+[\+|\-]*)} $line arg] == 1 && + ([string match "*\-*" $arg] == 1 || + [string first "\*" $line] > 0 || + [string match "*\+*" $arg] == 1) } { + + set task [string trim [string trimright $arg "-+"] ] + set l [string first "-" $line] + if {$l == -1} { + set l [string first "+" $line] + if {$l == -1} { + set l [string first "\*" $line] + } + } + set desc [ string range $line $l end ] + + # We now have the task name and the description string, format + # on output with the HREF defined. + set nblanks [expr 13 - [string length $task] ] + set fmtstr [format "%%%ds<A HREF=\"%%s\">%%s</A> %%s\n" $nblanks ] + set ostr [format $fmtstr $blank $task $task $desc] + + lappend results $ostr + + } elseif {[regexp {(^[a-zA-Z0-9\_]+\.[a-zA-Z0-9\_]+\:$)} $i val] == 1} { + + # Break out the task and package names. + regsub -all {[\.:]} $i " " val + scan $val "%s %s" parent child + + # Format a URL and append the results. + if { [ string match "*root*" $parent] == 0} { + set ref [format "<A HREF=\"%s\">%s</A>.<A HREF=\"%s\">%s</A>:\n"\ + $parent $parent $child $child ] + } else { + set ref [format "%s.<A HREF=\"%s\">%s</A>:\n"\ + $parent $child $child ] + } + lappend results $ref + + } else { + set nblanks [expr [string length $i] - [string length $line] ] + set fmtstr [format "%%%ds%%s\n" $nblanks ] + lappend results [format $fmtstr $blank $line ] + } + } + return [ join $results ] +} + + +# Generated a list of the lines and create the section menu. + +proc setSectionMenu { text args } { + global secMenuDescription + + # Break out the table of contents from the string. Note we're hard- + # wired here into the form of the comment string used to contain the + # section name. + set l [expr [string first "<! Contents: " $text] + 12] + if {$l == 0} { return } + set s [string range $text $l end] + set r [expr [string first ">" $s] - 4] + set t [string range $s 0 $r] + set lst [split $t '\''] + + # Now take the list generated and create the menu. + set items { } + lappend items " \"Top of Page\" f.exec \{ send helpText gotoId 0 \}" + lappend items " f.dblline " + foreach i $lst { + if {$i != " "} { + set i [ string trimright $i ] + regsub -all {[ ,.():;]} [string tolower $i] _ url + lappend items " \" $i \" f.exec \{ jumpToName #s_$url \}" + } + } + + if { [llength $items] == 3 } { + send secButton set sensitive False + editMenu secMenu secButton $secMenuDescription + } else { + editMenu secMenu secButton $items + send secButton set sensitive True + } +} + + +# Generated a list of the lines and create the parameter menu. +proc setParameterMenu { text args } { + global parMenuDescription + set items { } + foreach i [split $text "\n"] { + if {[string match "\<\! Sec*PARAMETERS*Level=0*" $i] == 1} { + set l [expr [string first "Line='" $i] + 6] + set s [string range $i $l end] + set r [expr [string first "\'" $s] - 1] + set t [string range $s 0 $r] + regsub -all {[\ ]} $t " " d ;# remove tabs + regsub -all {[\"]} $d "\\\"" entry + + set l [expr [string first "Label='" $i] + 7] + set s [string range $i $l end] + set r [expr [string first "\'" $s] - 1] + set t [string range $s 0 $r] + + lappend items " \"$entry\" f.exec \{ jumpToName #l_$t \}" + } + } + + if { [llength $items] == 0 } { + send parButton set sensitive False + editMenu parMenu parButton $parMenuDescription + } else { + editMenu parMenu parButton $items + send parButton set sensitive True + } +} + + +# Position the page to the requested href name. +proc jumpToName { name } { + global curtask curpack helpType helpOption + + send helpText gotoId [send helpText anchorToId $name] + send helpText retestAnchors + + # Now add a history record for the jump + addHistRecord $curpack $curtask $name $helpOption "" $helpType +} + + +# Utility routine to 'detab' a line and preserve format. +proc detab {str {tablen 8}} { + set a 0 + set i [string first "\t" $str] + while {$i != -1} { + set m { } + set j $i + while {[incr j] % $tablen} { append m { } } + set str [string range $str $a \ + [expr {$i-1}]]$m[string range $str [incr i] end] + set i [string first "\t" $str] + } + return $str +} + + +################################################################################ +# Navigation and History Callbacks +################################################################################ + +# Go back one page. +proc Back args { + global curtask curpack helpType helpOption + global HPkg HType HUrl HOpt HTask HFile htop hcurrent + + incr hcurrent -1 + if {$hcurrent >= 0} { + set item $HTask($hcurrent) + set pkg $HPkg($hcurrent) + set type $HType($hcurrent) + set h $hcurrent + + if { $item == "Home" } { + loadHomePage + } else { + if { $HType($h) == "file"} { + if {[info exists HFile($h)] == 1} { + loadHistItem $h pkg $HFile($h) help file + } else { + setAlert param old \ + [format "HFile param at %d not found" $hcurrent] + } + } else { + loadHistItem $h $HPkg($h) $HTask($h) $HOpt($h) \ + $HType($h) $HUrl($h) + } + } + + if {$hcurrent == 0} { + send htbButton set sensitive False + send htuButton set sensitive False + } + if {$hcurrent >= 0} { + send htfButton set sensitive True + send htuButton set sensitive True + } + } else { + set hcurrent 0 + } + editHistoryMenu + printHistStack "Back " +} ; send htbButton addCallback Back + + +# Go forward one page. +proc Forward args { + global curtask curpack helpType helpOption + global HPkg HType HUrl HOpt HTask HFile htop hcurrent + + incr hcurrent + if {$hcurrent <= $htop} { + set item $HTask($hcurrent) + set pkg $HPkg($hcurrent) + set type $HType($hcurrent) + set h $hcurrent + + if { $item == "Home" } { + loadHomePage + } else { + if { $HType($h) == "file"} { + if {[info exists HFile($h)] == 1} { + loadHistItem $h pkg $HFile($h) help file + } else { + setAlert param old \ + [format "HFile param at %d not found" $hcurrent] + } + } else { + loadHistItem $h $HPkg($h) $HTask($h) $HOpt($h) \ + $HType($h) $HUrl($h) + } + } + + if {$hcurrent == $htop } { + send htfButton set sensitive False + send htbButton set sensitive True + } else { + send htbButton set sensitive True + } + } else { + incr hcurrent -1 + } + editHistoryMenu + printHistStack "Forward " +} ; send htfButton addCallback Forward + + +# Go up to previous package, skipping over pages inbetween. +proc Up args { + global curtask curpack helpType helpOption + global HPkg HType HUrl HOpt HTask htop hcurrent + + # From the current page go back until we find a package + if {$HType($hcurrent) == "package"} { + set i [expr {$hcurrent-1} ] + } else { + set i $hcurrent + } + while {$HType($i) != "package" && $i >= 0} { + incr i -1 + } + + # Found package, go get it. + set hcurrent $i + if {$i == 0} { + loadHomePage ;# push a history record?? + } else { + GCmd load $HTask($i) [getPkgName $HPkg($i)] $HOpt($i) + } + + set curtask $HTask($hcurrent) ;# update the state of things + set curpack $HPkg($hcurrent) + set helpOption $HOpt($hcurrent) + set helpType $HType($hcurrent) + + send topicEntry set string $curpack ;# update topic entry string + + if {$hcurrent == 0} { ;# adjust navigation buttons + send htbButton set sensitive False + send htuButton set sensitive False + } + if {$hcurrent >= 0} { + send htfButton set sensitive True + send htuButton set sensitive True + } + editHistoryMenu + printHistStack "Forward " +} ; send htuButton addCallback Up + + +# Go straight to the homepage. +proc Home args { + global curtask curpack helpType helpOption + global HPkg HType HUrl HOpt HTask HFile htop hcurrent + + # Load the homepage. + loadHomePage + + # A Home command jumps over everything in the history list but we + # need to push a history record for it anyway. + addHistRecord $HPkg(0) $HTask(0) $HUrl(0) $HOpt(0) $HFile(0) $HType(0) + + send topicEntry set string "" + set curtask "" + set curpack "" + set helpType "package" + set helpType "help" +} ; send hthButton addCallback Home + + +# Load the homepage. +proc loadHomePage { args } { + global curtask curpack version showType + + GCmd help Home + + # Clean up. + set curtask "" + set curpack "" + send topicEntry set string "" + send toplevel set title $version +} + +# Clear all the history information. +proc histClear args { + global HPkg HType HUrl HOpt HTask HFile htop hcurrent + global visited + + # Clear the visited anchors list. + foreach i [array names visited] { + unset visited($i) + } + + # Clear the history stack. + for { set i [expr {$htop -1}] } { $i >= 0 } { incr i -1 } { + catch { + unset HType($i) + unset HOpt($i) + unset HTask($i) + unset HPkg($i) + unset HUrl($i) + unset HFile($i) + } + } + + # Reinitialize, but save the current page as the new history stack. + catch { + set HPkg(0) $HPkg($htop) ;# package + set HOpt(0) $HOpt($htop) ;# option + set HTask(0) $HTask($htop) ;# task + set HUrl(0) $HUrl($htop) ;# url + set HType(0) $HType($htop) ;# type + set HFile(0) $HFile($htop) ;# filename + } + set htop 0 + set hcurrent 0 + + # Update navigation options and history menu. + send htbButton set sensitive False + send htfButton set sensitive False + send htuButton set sensitive False + editHistoryMenu +} + + +# Push an item on the history stack. +proc addHistRecord { pkg task url opt file type } { + global HPkg HType HUrl HOpt HTask HFile htop hcurrent + global helpType helpOption + global historyMenuDescription + + # Push a new history record to the top of the stack and make that the + # current record. + incr htop + set HPkg($htop) $pkg + set HTask($htop) $task + set HUrl($htop) $url + set HOpt($htop) $opt + set HFile($htop) [ expr {($file == "") ? "none" : $file } ] + set HType($htop) $type + set hcurrent $htop + + # Activate the Back button. + if {$hcurrent == 1} { + send htbButton set sensitive True + if {$type == "package"} { + send htuButton set sensitive True + } + } + + # Edit the history menu. + editHistoryMenu + printHistStack "addHistRecord" +} + + +# Edit the history menu to reflect the current state. +proc editHistoryMenu { args } { + global HPkg HType HUrl HOpt HTask htop hcurrent + global helpType helpOption + global historyMenuDescription + global navMenuDescription + global MAX_MENU_SIZE + + set items $historyMenuDescription + set nitems 0 + if {$htop > $MAX_MENU_SIZE} { + set nstart [ min $htop [expr {$hcurrent + 3}] ] + } else { + set nstart $htop + } + for { set i $nstart } { $i >= 0 } { incr i -1 } { + set pkg $HPkg($i) + set task $HTask($i) + set type $HType($i) + set opt $HOpt($i) + set url $HUrl($i) + if {$pkg != "" || $type == "file"} { + if {$type == "task"} { + if {$url == ""} { + set entry [format "%-22.22s %4s" $task \ + [menuItemType $type $url $opt ] ] + } else { + set entry [format "%-22.22s %4s" \ + [ format "%s (%s)" $task [string trimleft $url "#"] ] \ + [menuItemType $type $url $opt ] ] + } + } elseif {$type == "package"} { + set entry [format "%-22.22s %4s" [getPkgName $pkg] \ + [menuItemType $type $url $opt ] ] + } elseif {$type == "file"} { + upvar #0 HFile file + set entry [format "%s" $file($i) ] + } else { + setAlert param old [format "Unknown help type: %s" $type] + } + + if {$type == "file"} { + lappend items " \" $entry \" f.exec \{ \ + loadHistItem $i pkg $entry help file \} \ + bitmap \{\($i==$hcurrent\) ? \"arrow\" : \"null\" \} " + } else { + lappend items " \" $entry \" f.exec \{ \ + loadHistItem $i [getPkgName $pkg] $task $opt $type $url \} \ + bitmap \{\($i==$hcurrent\) ? \"arrow\" : \"null\" \} " + } + } + + incr nitems 1 + if {$nitems > $MAX_MENU_SIZE} { + lappend items "f.dblline" + lappend items " \" History truncated... \" f.exec \{ \} " + break + } + } + editMenu historyMenu historyButton $items + + # Edit the navigation menu to get the sensitivities right for + # the current state. + editMenu navMenu helpText $navMenuDescription +} + + +# Utility routine to set the history item entry type. +proc menuItemType { type url opt } { + if {$url != ""} { + return [format "Link"] + } + + switch $opt { + "help" { return [format "%s" [expr {($type=="task")?"Task":"Pkg"} ]] } + "source" { return [format "(src)"] } + "sysdoc" { return [format "(sys)"] } + } +} + + +# Load a particular page/link from the history list. +proc loadHistItem { itemno pkg task opt type args } { + global HPkg HType HUrl HOpt HTask htop hcurrent + global curtask curpack helpType helpOption hcurrent + global version + + # Load the requested page. Check whether we just need to jump to + # the current page. + if {$task == "Home"} { + loadHomePage + + } elseif {$type == "file"} { + GCmd directory open $task + + } elseif {$itemno == $hcurrent || \ + ($pkg != $curpack || \ + $task != $curtask || \ + $type != $helpType || \ + $opt != $helpOption) } { + GCmd load $task $pkg $opt + } + + # If the history item included an internal link, jump to it. The + # 'args' value will either be the URL or an empty string. + if {$args != ""} { + send helpText gotoId [send helpText anchorToId $args] + send helpText retestAnchors + } + + # Update the topic entry string. + if { $type == "task" } { + send topicEntry set string [ format "%s.%s" $pkg $task ] + } elseif { $type == "file" } { + send topicEntry set string $task + } else { + send topicEntry set string $pkg + } + + # Change the options button if needed. + if {$HOpt($itemno) != $helpOption} { + send [ getOptWidget $helpOption ] set on 0 + setOptColor [ getOptWidget $HOpt($itemno) ] green + } + + # Update the current entry. + set hcurrent $itemno + + if { $type != "file" } { + set curtask $HTask($hcurrent) + set curpack $HPkg($hcurrent) + set helpOption $HOpt($hcurrent) + set helpType $HType($hcurrent) + } else { + set helpOption "help" + set helpType "file" + } + + # Tweak the navigation buttons. + if {$hcurrent == 0} { + send htbButton set sensitive False + send htuButton set sensitive False + } + if {$hcurrent >= 0} { + send htfButton set sensitive True + send htuButton set sensitive True + } + if {$hcurrent == $htop } { + send htfButton set sensitive False + send htbButton set sensitive True + } + + # Edit the history menu. + editHistoryMenu +} + +# Initialize the history menu. +editHistoryMenu + +# Given the option type return the widget name. +proc getOptWidget { opt } { + switch $opt { + "help" { return "hlpOpt" } + "source" { return "srcOpt" } + "sysdoc" { return "sysOpt" } + } +} + +# Debug utility to print the history stack. +proc printHistStack { where args } { + global HPkg HType HUrl HOpt HTask HFile htop hcurrent + global debug + + # Print the stack... + if {$debug > 0} { + print "_______________________________________________________________" + print $where + for { set i $htop } { $i >= 0 } { incr i -1 } { + if {$HType($i) == "file"} { + upvar #0 HFile file + print [format "%3s%d: type=%1.1s file=%s\n"\ + [ expr {($i==$hcurrent) ? ">>>" : "---"} ] \ + $i $HType($i) $file($i) ] + } else { + print [format "%3s%d: type=%1.1s opt=%4.4s task=%s pack=%s\n"\ + [ expr {($i==$hcurrent) ? ">>>" : "---"} ] \ + $i $HType($i) $HOpt($i) $HTask($i) $HPkg($i) $HUrl($i) ] + } + } + } +} + +# Test whether an anchor has been visited. +proc testAnchor {widget cbtype href} { + global visited + return [info exists visited($href)] +} +send hlpText addCallback testAnchor testAnchor +send helpText addCallback testAnchor testAnchor +send resList addCallback testAnchor testAnchor + + +################################################################################ +# Options Menu +################################################################################ + +proc setType { param old new } { + global helpType + set helpType [string tolower $new ] +} ; send type addCallback setType + +proc selectOption { widget type value args } { + global curtask curpack helpOption + + if { $curtask != "" } { + foreach i { hlpOpt srcOpt sysOpt } { send $i set on 0 } + setOptColor $widget green + send $widget set on 1 + switch $widget { + hlpOpt { set helpOption help + send fmtText setSensitive true + send fmtPS setSensitive true + } + srcOpt { set helpOption source + send fmtText setSensitive false + send fmtPS setSensitive false + } + sysOpt { set helpOption sysdoc + send fmtText setSensitive true + send fmtPS setSensitive true + } + } + GCmd help $curtask [getParentName $curpack] $helpOption + } +}; foreach i {hlpOpt srcOpt sysOpt } { send $i addCallback selectOption } + +proc toggleFileOption { args } { + if { [ send filOpt get on] == 1 } { + send fileShell map + } else { + send fileShell unmap + } +} ; send filOpt addCallback toggleFileOption + +send flDismiss addCallback "send fileShell unmap ; send filOpt set on 0" + + +################################################################################ +# Procedure used by the printer prompt box. +################################################################################ + +proc setPrinterName { param old new } { + send printEntry set string $new +}; send printer addCallback setPrinterName + +set page_size pageLetter + +proc pageRadio { widget type state args } { + global page_size + + if {$state == 0} { + # Don't allow a button to be turned off. + send $widget set on 1 + } else { + send $page_size set on 0 + set page_size $widget + } +} +foreach w {pageLetter pageLegal pageA4 pageB5} { send $w addCallback pageRadio } + +proc toPrinterToggle args { + global curtask HType hcurrent + if { [send toPrinter get on] } { + send toFile set on False + send printLabel set label "Printer: " + send printEntry set string "printer" + } else { + send toFile set on True + send printLabel set label "File Name: " + if {$HType($hcurrent) == "file" || [send srcOpt get on] == 1} { + send printEntry set string [format "%s" [fileSource] ] + } else { + send printEntry set string [format "%s.ps" $curtask] + } + } +} ; send toPrinter addCallback toPrinterToggle + +proc toFileToggle args { + global curtask HType hcurrent + if { [send toFile get on] } { + send toPrinter set on False + send printLabel set label "File Name: " + if {$HType($hcurrent) == "file" || [send srcOpt get on] == 1} { + send printEntry set string [format "%s" [fileSource] ] + } else { + send printEntry set string [format "%s.ps" $curtask] + } + } else { + send toPrinter set on True + send printLabel set label "Printer: " + send printEntry set string "printer" + } +} ; send toFile addCallback toFileToggle + +proc doPrintOkay { args } { + global curtask curpack HType hcurrent + + set device [ send printEntry get string ] + if { [send toPrinter get on] } { + GCmd print $curtask $curpack $device + } else { + if {$HType($hcurrent) == "file" || [send srcOpt get on] == 1} { + GCmd directory save [fileSource] $fname 1 source + } else { + GCmd directory save [fileSource] $fname 1 postscript + } + } + send printShell unmap +} +send printOkay addCallback doPrintOkay +send printEntry addCallback doPrintOkay + +send printDismiss addCallback "send printShell unmap " + + +################################################################################ +# Procedures used by the fileBrowser. +################################################################################ + +# File browsing globals +set curdir "" ;# current directory +set pattern "*" ;# filename template +set format "fmtSrc" ;# SaveAs format + + +# Browser selection callback. +proc browserSelect { widget event args } { + global curdir helpOption + + set opt [expr {$widget == "dirList" ? "dirlist" : "loadfile"}] + set item [send $widget getItem itemno] + send $widget getItem itemno + set mode [send fbcOkay get label] + + if { $itemno != "none" } { + if { $mode == "Load"} { + if {$opt != "dirlist"} { + addHistRecord "" "" "" help [format "%s%s" $curdir $item] "file" + } + GCmd directory $opt $item + send flistText set string [format " file Okay %s%s\n" \ + $curdir $item] + } else { + if {$opt == "dirlist"} { + GCmd directory $opt $item + } else { + send fnameEntry set string [format "%s%s" $curdir $item] + } + } + } +} +send dirList addEventHandler browserSelect buttonReleaseMask +send fileList addEventHandler browserSelect buttonReleaseMask + + +# Client callback. +proc browserListing { param old new } { + global curdir pattern + + set option [ lindex $new 0 ] + switch $option { + dirlist { set list [lindex $new 1] + send dirList setList $list resize + } + filelist { set list [lindex $new 1] + send fileList setList $list resize + } + template { set pattern [lindex $new 1] + send filterEntry set string $pattern + } + curdir { set curdir [lindex $new 1] + send curdirVal set label $curdir + } + selection { send fnameEntry set string [lindex $new 1] } + } +} ; send directory addCallback browserListing + + +# Set the filename matching template. +proc setTemplate { widget mode pattern args } { + GCmd directory template $pattern +} ; send filterEntry addCallback setTemplate + + +# get the filename of the currently displayed page. +proc fileSource { args } { + global helpOption + + set str [ send flistText get string ] + + set fname "" + for {set i 0} {$i < [llength $str]} {incr i 3} { + set j [expr {$i + 2} ] + if {($helpOption == "source" && [lindex $str $i] == "src") || + ($helpOption == "sysdoc" && [lindex $str $i] == "sys") || + ($helpOption == "help" && [lindex $str $i] == "hlp") || + ($helpOption == "file" && [lindex $str $i] == "file")} { + set fname [lindex $str $j] + break + } + } + return $fname +} + +# Open a specific file, either to load a new page or save the current page. +proc openFile { widget args } { + global curdir helpOption + + set fname [send fnameEntry get string] + + if {$fname == ""} { + setAlert param old "No filename specified" + } else { + if { [send fbcOkay get label] == "Load"} { + addHistRecord "" "" "" "" [format "%s%s" $curdir $fname] "file" + GCmd directory open $fname + send flistText set string [format " file Okay %s\n" $fname] + } else { + set page [fileSource] + set ow [send overwrite get on] + if {[send fmtSrc get on] == 1} { + GCmd directory save $page $fname $ow source + } elseif {[send fmtText get on] == 1} { + GCmd directory save $page $fname $ow text + } elseif {[send fmtHTML get on] == 1} { + GCmd directory save $page $fname $ow html + } elseif {[send fmtPS get on] == 1} { + GCmd directory save $page $fname $ow postscript + } + } + } +} ; send fbcOkay addCallback openFile + + +# Make the SaveAs formats a radio box. +proc fmtRadio { widget type state args } { + global format + + if {$state == 0} { + # Don't allow a button to be turned off. + send $widget set on 1 + } else { + send $format set on 0 + set format $widget + } + + # If there's no filename specified set one as a default. + setDefaultFname + +} ; foreach w {fmtSrc fmtText fmtHTML fmtPS} { send $w addCallback fmtRadio } + + +# Set a default filename based on the selected format and task name +proc setDefaultFname args { + global format curtask curdir + + set fname [send fnameEntry get string] + if {$curtask != ""} { + switch $format { + fmtSrc { send fnameEntry \ + set string [format "%s%s" $curdir $curtask] } + fmtText { send fnameEntry \ + set string [format "%s%s.txt" $curdir $curtask] } + fmtHTML { send fnameEntry \ + set string [format "%s%s.html" $curdir $curtask] } + fmtPS { send fnameEntry \ + set string [format "%s%s.ps" $curdir $curtask] } + } + } +} + +proc browserHelp args { + if { [send fbcOkay get label] == "Load"} { + showHelp lfiles + } else { + showHelp sfiles + } +} ; send fbcHelp addCallback browserHelp + +send fnavHome addCallback "GCmd directory home" +send fnavUp addCallback "GCmd directory up" +send fnavRoot addCallback "GCmd directory root" +send fnavRescan addCallback "GCmd directory rescan" +send fnameClear addCallback "send fnameEntry set string \"\"" +send filterClear addCallback "send filterEntry set string \"\"" +send fbcDismiss addCallback "send fileBrowser unmap" + + + +################################################################################ +# Procedures used by the find box. +################################################################################ + +proc doFindOkay args { + set dir forward + set case caseless + set phrase [send findEntry get string] + + if { $phrase != "" } { + if { [send findDir get on] } { set dir backward } + if { [send findCase get on] } { set case caseSensitive } + + if { [send helpText searchText $phrase start end $dir $case] > 0 } { + set elid [lindex [lindex $start 0] 0] + set id [max 1 [expr $elid - 10] ] + + send helpText gotoId $id + send helpText setSelection $start $end + } else { + send warnText set label "Search string not found." + send warning map + } + } else { + send warnText set label "Warning: No search phrase entered." + send warning map + } +} ; foreach w { findOkay findEntry } { send $w addCallback doFindOkay } + +send findClear addCallback { send findEntry set string "" } +send findDismiss addCallback { send findShell popdown } + + +################################################################################ +# Procedures used by the apropos prompt box. +################################################################################ + +proc doSearchOkay args { + set phrase [send searchEntry get string] + if { $phrase != "" } { + send searchStatus set label "Searching..." + GCmd search [send exactMatch get on] $phrase + } else { + send warnText set label "Warning: No search phrase entered." + send warning map + } +} ; foreach w { searchOkay searchEntry } { send $w addCallback doSearchOkay } + +proc searchResults { param old new } { + global search_mapped + + if {$search_mapped == 0} { + Search + } + send resList setText $new + send resList retestAnchors + send searchStatus set label "" +} ; send apropos addCallback searchResults + +# Selection callback. +proc searchAnchorSelected {widget cbtype event text href args} { + global helpOption helpType curpack curtask + global visited + + # Break out the task and package names. + set pack [lindex [split $href "."] 0] + set task [lindex [split $href "."] 1] + + # Set the state and load the page. + if {$helpOption != "help"} { + send [getOptWidget $helpOption] set on 0 + setOptColor hlpOpt green + } + set curtask $task + set curpack $pack + set helpOption "help" + set helpType [expr {($pack == $task) ? "package" : "task"}] + GCmd load $curtask $curpack $helpOption + + # Add the history record, one for the package and one for the task. + addHistRecord $curpack $curpack "" $helpOption "" "package" + if {$pack != $task} { + addHistRecord $curpack $curtask "" $helpOption "" "task" + } + send htbButton set sensitive True + send htuButton set sensitive True + editHistoryMenu + printHistStack "searchAnchorSelected" + + # Update the topic entry string. + if { $task == $pack } { + send topicEntry set string $pack + } else { + send topicEntry set string [ format "%s.%s" $pack $task ] + } + + set visited($href) 1 + send resList retestAnchors + +} ; send resList addCallback searchAnchorSelected anchor + +proc doSearchClear args { + send searchEntry set string "" +} ; send searchClear addCallback doSearchClear + +proc doSearchDismiss args { + global search_mapped + + set search_mapped 0 + send searchShell unmap +} ; send searchDismiss addCallback doSearchDismiss + +send searchHelp addCallback { showHelp search } + + +################################################################################ +# Define procedures for the help panel +################################################################################ + +# Stuff for keeping track of visited anchors. +set h_links { 0 } +set h_linkIndex 0 + +proc getHelpText { param old new } { + send hlpText setText $new +}; send help addCallback getHelpText + +proc anchorSelected {widget cbtype event text href args} { + global visited h_links h_linkIndex + set anchID [send hlpText anchorToId $href] + set visited($href) 1 + if {$h_linkIndex == 0} { + send hlpBack set sensitive True + if {[lindex $h_links 1] != $anchID} { + set h_links { 0 } + send hlpForward set sensitive False + } + } + if {$h_linkIndex > 0 && \ + [lindex $h_links [expr $h_linkIndex + 1]] != $anchID} { + #set h_links [lrange $h_links 0 $h_linkIndex] + set pos [send hlpText positionToId 0 0] + set h_links [lreplace $h_links $h_linkIndex end $pos] + } + if {[lindex $h_links [expr $h_linkIndex + 1]] != $anchID} { + lappend h_links $anchID + incr h_linkIndex + } else { + send hlpForward set sensitive False + incr h_linkIndex + } + if {$h_linkIndex == [expr [llength $h_links] - 1]} { + send hlpForward set sensitive False + } + send hlpText gotoId $anchID + send hlpText retestAnchors +}; send hlpText addCallback anchorSelected anchor + + +# Callbacks to position forwards and backwards in link list. +proc hlpForward args { + global h_links h_linkIndex + incr h_linkIndex + if {$h_linkIndex <= [llength $h_links]} { + set anchID [lindex $h_links $h_linkIndex] + send hlpText gotoId $anchID + send hlpText retestAnchors + if {$h_linkIndex == [expr [llength $h_links] - 1]} { + send hlpForward set sensitive False + send hlpBack set sensitive True + } else { + send hlpBack set sensitive True + } + } else { + incr h_linkIndex -1 + } +}; send hlpForward addCallback hlpForward + +proc hlpBack args { + global h_links h_linkIndex + incr h_linkIndex -1 + if {$h_linkIndex >= 0} { + set anchID [lindex $h_links $h_linkIndex] + send hlpText gotoId $anchID + send hlpText retestAnchors + if {$h_linkIndex == 0} { send hlpBack set sensitive False } + if {$h_linkIndex >= 0} { send hlpForward set sensitive True } + } else { + incr h_linkIndex 1 + } +}; send hlpBack addCallback hlpBack + +proc hlpHome args { + global h_links h_linkIndex + set h_links { 0 } + set h_linkIndex 0 + send hlpText gotoId 0 + send hlpForward set sensitive False + send hlpBack set sensitive False +}; send hlpHome addCallback hlpHome + +proc hlpTutorial args { + showHelp tutorial +}; send hlpTutorial addCallback hlpTutorial +send hlpTutorial unmap ;# NO TUTORIAL AT THE MOMENT + +proc showHelp {name args} { + anchorSelected widget cbtype event text #$name + send hlpShell map +} + +proc hlpFind args { + set phrase [send hfEntry get string] + set dir forward + set case caseless + + if { $phrase != "" } { + if { [send hfDir get on] } { set dir backward } + if { [send hfCase get on] } { set case caseSensitive } + if {[send hlpText searchText $phrase start end $dir $case ] > 0} { + set elid [lindex [lindex $start 0] 0] + set id [max 1 [expr $elid - 10] ] + send hlpText gotoId $id + send hlpText setSelection $start $end + } else { + send warnText set label "Search string not found." + send warning map + } + } else { + send warnText set label "Warning: No search phrase entered." + send warning map + } +} ; foreach w { hfEntry hfFind } { send $w addCallback hlpFind } + +send hfClear addCallback { send hfEntry set string "" } + +send hlpDismiss addCallback "send hlpShell unmap" + + +################################################################################ +# Document source viewer procedures. +################################################################################ + +proc srcOpen { args } { send doc_source map } +send srcDismiss addCallback "send doc_source unmap" + + +################################################################################ +# Define some TCL debug procedures +################################################################################ + +proc tclOpen {} { send tclShell map } + +proc tclCommandClear { widget args } { + send tclEntry set string "" +} ; send tclClear addCallback tclCommandClear + +proc tclCommandExecute { widget args } { \ + send server [send tclEntry {get string}] +} ; send tclExecute addCallback tclCommandExecute + +proc tclCommand { widget mode command args } { + send server $command +} ; send tclEntry addCallback tclCommand + +proc tclToggleLogging args { + global debug + if { [ send tclLogging get state] } { + set debug 1 + send tclLogging set label "Disable Logging" + } else { + set debug 0 + send tclLogging set label "Enable Logging" + } +} ; tclToggleLogging +send tclLogging addCallback tclToggleLogging + +send tclDismiss addCallback "send tclShell unmap" + +# Connect the 'textout' parameter so it appends messages from +# the client to the Tcl text window. +proc tclLogMessages { param old new } { + global debug + if {$debug == 1} { send tclEntry append [format "%s\n" $new ] } +} ; send textout addCallback tclLogMessages + + +################################################################################ +# Warning dialog. This pops up a dialog box with the given warning message. +################################################################################ + +proc warnOkay {widget args} { + global curpack curtask + + set label [send warnText get label] + if {[string match "No*" $label ] == 1} { + set topic [send topicEntry get string] + set last [string last "." $topic ] + send topicEntry set string [ string range $topic 0 [ incr last -1 ] ] + } + send warning unmap +}; send warnDismiss addCallback warnOkay + + +# The parameter "alert" is used to forward alerts from the client. The +# special 'dismiss' value can be used to shut down the alert from the +# client, the special "pop" value pops the last history elements from the +# stack (used in case of an error loading a file). + +proc setAlert {param old new} { + global HPkg HType HUrl HOpt HTask HFile htop hcurrent + + if {$new == "dismiss"} { + send warning unmap + } elseif {$new == "pop"} { + catch { + unset HType($hcurrent) + unset HOpt($hcurrent) + unset HTask($hcurrent) + unset HPkg($hcurrent) + unset HUrl($hcurrent) + unset HFile($hcurrent) + } + incr hcurrent -1 + } else { + send searchStatus set label "" + send warnText set label $new + send warning map + } +}; send alert addCallback setAlert + + diff --git a/pkg/system/help/xhelp/mkpkg b/pkg/system/help/xhelp/mkpkg new file mode 100644 index 00000000..a12b2788 --- /dev/null +++ b/pkg/system/help/xhelp/mkpkg @@ -0,0 +1,28 @@ +# Make the GUI part of the HELP task. + +$checkout libpkg.a ../ +$update libpkg.a +$checkin libpkg.a ../ +$exit + +zzdebug: + $omake zzdebug.x + $link zzdebug.o -l xtools + ; + +libpkg.a: + xhelp.x ../help.h xhelp.h + xhcmds.x ../help.h xhelp.h + xhdir.x xhelp.h <ctype.h> <diropen.h> <finfo.h> + xhfiles.x ../help.h xhelp.h <ctype.h> <fset.h> + xhhelp.x ../help.h xhelp.h <error.h> <finfo.h> <fset.h> + xhinit.x xhelp.h + xhofile.x xhelp.h <fset.h> + xhpkg.x <error.h> <fset.h> ../helpdir.h ../help.h xhelp.h + xhprint.x xhelp.h ../help.h <ctype.h> <error.h> <ttyset.h> + xhqref.x ../help.h xhelp.h <ctype.h> <finfo.h> + xhroot.x xhelp.h + xhsave.x ../help.h xhelp.h <ctype.h> + xhsearch.x xhelp.h <ctype.h> <fset.h> + xhsort.x xhelp.h <ctype.h> + ; diff --git a/pkg/system/help/xhelp/xhcmds.x b/pkg/system/help/xhelp/xhcmds.x new file mode 100644 index 00000000..2c98af79 --- /dev/null +++ b/pkg/system/help/xhelp/xhcmds.x @@ -0,0 +1,185 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <syserr.h> +include "../help.h" +include "xhelp.h" + + +# XHELP callback commands. +define XC_COMMANDS "|help|load|print|quit|search|files|directory|type|package|" +define CMD_HELP 1 +define CMD_LOAD 2 +define CMD_PRINT 3 +define CMD_QUIT 4 +define CMD_SEARCH 5 +define CMD_FILES 6 +define CMD_DIRECTORY 7 +define CMD_TYPE 8 +define CMD_PACKAGE 9 + + +# XH_COMMAND_LOOP -- Process the GUI command loop. + +procedure xh_command_loop (xh) + +pointer xh #I task descriptor + +pointer sp, cmd, name, pkg, pat, opt, dev +real x, y +int wcs, key, exact_match +char str[SZ_FNAME] + +bool streq() +int strdic(), clgcur() +int xh_pkglist() + +begin + call smark (sp) + call salloc (name, SZ_FNAME, TY_CHAR) + call salloc (pkg, SZ_FNAME, TY_CHAR) + call salloc (opt, SZ_FNAME, TY_CHAR) + call salloc (dev, SZ_FNAME, TY_CHAR) + call salloc (cmd, SZ_FNAME, TY_CHAR) + call salloc (pat, SZ_FNAME, TY_CHAR) + + + # Enter the command loop. + while (clgcur ("coords", x, y, wcs, key, str, SZ_FNAME) != EOF) { + + # Skip any non-colon commands. + if (key != ':') + next + + # Get the colon command string. + call sscan (str) + call gargwrd (Memc[cmd], SZ_FNAME) + + switch (strdic (Memc[cmd], Memc[cmd], SZ_FNAME, XC_COMMANDS)) { + case CMD_HELP: + call gargwrd (Memc[name], SZ_FNAME) + + # Get help on the requested topic, updates package list + # if necesary. + if (streq(Memc[name],"Home")) { + call xh_init (xh, NO, YES) + } else { + call gargwrd (Memc[pkg], SZ_FNAME) # curpack + call gargwrd (Memc[opt], SZ_FNAME) # option + call xh_cmd_help (xh, Memc[name], Memc[pkg], Memc[opt]) + } + + case CMD_FILES: + call gargwrd (Memc[name], SZ_FNAME) # task name + call gargwrd (Memc[pkg], SZ_FNAME) # parent package + call xh_files (xh, Memc[name], Memc[pkg]) + + case CMD_LOAD: + # Load a requested page from the history. + call gargwrd (Memc[name], SZ_FNAME) # task name + call gargwrd (Memc[pkg], SZ_FNAME) # curpack + call gargwrd (Memc[opt], SZ_FNAME) # help option + if (xh_pkglist (xh, Memc[name], HELPDB(xh), LIST(xh)) != 0) + call gmsg (XH_GP(xh), "pkglist", LIST(xh)) + call xh_help (xh, Memc[name], Memc[pkg], Memc[opt]) + + case CMD_PRINT: + # Print the current results. + call gargwrd (Memc[name], SZ_FNAME) # task name + call gargwrd (Memc[pkg], SZ_FNAME) # curpack + call gargwrd (Memc[dev], SZ_FNAME) # printer name + call xh_print_help (xh, Memc[name], Memc[pkg], Memc[dev]) + + case CMD_QUIT: + # Quit the task. + break + + case CMD_SEARCH: + # Get the results of the keyword search. + call gargi (exact_match) + call gargstr (Memc[pat], SZ_FNAME) + call xh_search (xh, exact_match, Memc[pat]) + + case CMD_DIRECTORY: + # Process the directory browsing command. + call gargwrd (Memc[opt], SZ_FNAME) + call xh_directory (xh, Memc[opt]) + + case CMD_TYPE: + # Get the showtype value from the GUI + call gargi (XH_SHOWTYPE(xh)) + + case CMD_PACKAGE: + # For the given item return the package in which it + # was found. [DEBUG ROUTINE.] + call gargwrd (Memc[name], SZ_FNAME) + call xh_pkgpath (xh, Memc[name], CURPACK(xh), Memc[pkg]) + call printf ("%s => %s\n") + call pargstr (Memc[name]) + call pargstr (Memc[pkg]) + call flush(STDOUT) + } + } + + call sfree (sp) +end + + +# XH_CMD_HELP -- Process a help command. + +procedure xh_cmd_help (xh, topic, curpack, option) + +pointer xh # task descriptor +char topic[ARB] # requested topic +char curpack[ARB] # current package +char option[ARB] # option (help|source|sysdoc) + +int len + +bool streq() +int strncmp() +int xh_pkgname(), xh_pkglist() + +begin + if (streq (option, "help")) { + # No package name given, find one and load it. + if (streq (curpack, "{}")) { + curpack[1] = EOS + len = 0 + if (xh_pkgname (xh, topic, curpack) == OK) + len = xh_pkglist (xh, curpack, HELPDB(xh), LIST(xh)) + + if (len != 0 && + strncmp(curpack, "root", 4) != 0 && + strncmp(curpack, "clpack", 6) != 0) { + call gmsg (XH_GP(xh), "pkglist", LIST(xh)) + call strcpy (curpack, CURPACK(xh), SZ_FNAME) + call gmsg (XH_GP(xh), "curpack", curpack) + call gmsg (XH_GP(xh), "history", "package") + } + } + + if (xh_pkglist (xh, topic, HELPDB(xh), LIST(xh)) != 0) { + # Got a package listing.... + call gmsg (XH_GP(xh), "pkglist", LIST(xh)) + call strcpy (topic, CURPACK(xh), SZ_FNAME) + call gmsg (XH_GP(xh), "curpack", topic) + } + } + + if (streq (topic, CURPACK(xh))) { + call gmsg (XH_GP(xh), "type", "package") + call gmsg (XH_GP(xh), "curtask", topic) + if (streq (option, "help")) + call xh_help (xh, "", CURPACK(xh), option) + else + call xh_help (xh, topic, curpack, option) + call strcpy (CURPACK(xh), CURTASK(xh), SZ_FNAME) + + } else { + call gmsg (XH_GP(xh), "type", "task") + call gmsg (XH_GP(xh), "curtask", topic) + call xh_help (xh, topic, CURPACK(xh), option) + call strcpy (topic, CURTASK(xh), SZ_FNAME) + } + call gmsg (XH_GP(xh), "history", "append") +end diff --git a/pkg/system/help/xhelp/xhdir.x b/pkg/system/help/xhelp/xhdir.x new file mode 100644 index 00000000..3c951afa --- /dev/null +++ b/pkg/system/help/xhelp/xhdir.x @@ -0,0 +1,567 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <diropen.h> +include <ctype.h> +include <finfo.h> + +include "xhelp.h" + + +# Pattern matching definitions. +define PATCHARS "*?[" + +# Browsing command dictionary. +define DIR_CMDS "|dirlist|loadfile|open|template|home|up|root|rescan|save|" +define DIRLIST 1 # get the directory listing +define LOADFILE 2 # load the requested file +define OPEN 3 # load the requested file +define TEMPLATE 4 # filename matching template +define HOME 5 # goto the user's home$ +define UP 6 # go up one directory +define ROOT 7 # go to the root directory +define RESCAN 8 # rescan current directory +define SAVE 9 # save to the requested file + + +# XH_DIRECTORY -- Process the directory browsing command. + +procedure xh_directory (xh, command) + +pointer xh #i task descriptor +char command[ARB] #i command option + +pointer sp, dir, file, pattern, path, fmt +pointer task, pkg, opt, type +int ncmd, overwrite +int strdic(), strcmp(), envgets() + +begin + # Allocate working space and clear it. + call smark (sp) + call salloc (dir, SZ_PATHNAME, TY_CHAR) + call salloc (path, SZ_PATHNAME, TY_CHAR) + call salloc (file, SZ_FNAME, TY_CHAR) + call salloc (pattern, SZ_FNAME, TY_CHAR) + call salloc (fmt, SZ_FNAME, TY_CHAR) + call salloc (task, SZ_FNAME, TY_CHAR) + call salloc (pkg, SZ_FNAME, TY_CHAR) + call salloc (opt, SZ_FNAME, TY_CHAR) + call salloc (type, SZ_FNAME, TY_CHAR) + + call aclrc (Memc[dir], SZ_FNAME) + call aclrc (Memc[path], SZ_FNAME) + call aclrc (Memc[file], SZ_FNAME) + call aclrc (Memc[fmt], SZ_FNAME) + call aclrc (Memc[pattern], SZ_FNAME) + call aclrc (Memc[task], SZ_FNAME) + call aclrc (Memc[pkg], SZ_FNAME) + call aclrc (Memc[opt], SZ_FNAME) + call aclrc (Memc[type], SZ_FNAME) + + ncmd = strdic (command, command, SZ_LINE, DIR_CMDS) + switch (ncmd) { + case DIRLIST: + call gargwrd (Memc[dir], SZ_PATHNAME) # get the dirname + if (strcmp ("../", Memc[dir]) == 0) { + call xh_updir (xh) + } else { + call sprintf (Memc[path], SZ_PATHNAME, "%s%s") + call pargstr (CURDIR(xh)) + call pargstr (Memc[dir]) + call xh_set_curdir (xh, Memc[path]) + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + call xh_selection (xh, CURDIR(xh)) + } + + case LOADFILE: + call gargwrd (Memc[file], SZ_FNAME) # get the filename + call sprintf (Memc[path], SZ_PATHNAME, "%s%s") + call pargstr (CURDIR(xh)) + call pargstr (Memc[file]) + call xh_open_file (xh, "helpres", Memc[path], YES, YES) + call xh_selection (xh, Memc[path]) + + case OPEN: + call gargwrd (Memc[file], SZ_FNAME) # get the filename + call xh_ldfile (xh, Memc[file]) + + case TEMPLATE: + call gargwrd (Memc[pattern], SZ_FNAME) # set the template + call xh_set_pattern (xh, Memc[pattern]) + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + + case HOME: + if (envgets ("home", Memc[dir], SZ_PATHNAME) != EOF) { + call xh_set_curdir (xh, Memc[dir]) + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + } + + case UP: + call xh_updir (xh) + + case ROOT: + call xh_set_curdir (xh, "/") + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + + case RESCAN: + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + + case SAVE: + call gargwrd (Memc[path], SZ_FNAME) # get the filename + call gargwrd (Memc[file], SZ_FNAME) # get the output fname + call gargi (overwrite) # get the overwrite flag + call gargwrd (Memc[fmt], SZ_FNAME) # get the save format + call xh_save_file (xh, Memc[path], Memc[file], Memc[fmt], + overwrite) + } + + call sfree (sp) +end + + +# XH_DIRLIST -- Given the directory name and a file template return the +# directory contents. + +procedure xh_dirlist (xh, directory, pattern) + +pointer xh #i task descriptor +char directory[ARB] #i directory to read +char pattern[ARB] #i matching template + +pointer sp, path, fname, patbuf +pointer dp, fp, ip, op, ep, sym +bool match_extension +int dd, n, patlen +int nfiles, ndirs, lastch + +pointer stopen(), stenter() +int diropen(), xh_isdir(), strncmp(), stridxs() +int patmake(), patmatch(), strlen(), getline() + +begin + call smark (sp) + call salloc (path, SZ_PATHNAME, TY_CHAR) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (patbuf, SZ_LINE, TY_CHAR) + + call aclrc (Memc[patbuf], SZ_LINE) + + # If this isn't a directory just return silently. + if (xh_isdir (directory, Memc[path], SZ_PATHNAME) == 0) { + call sfree (sp) + return + } + + # Open the requested directory + dd = diropen (directory, PASS_HIDDEN_FILES) + + # Set up the pattern matching code. We recognize selecting all files + # with a particular extension as a special case, since this case is + # very common and can be done much more efficiently if we don't use + # the general pattern matching code. If we have no pattern set the + # length to zero to indicate that everything will match. + + if (pattern[1] == EOS) { + patlen = 0 + } else { + match_extension = (strncmp (pattern, "*.", 2) == 0 && + stridxs (PATCHARS, pattern[3]) <= 0) + if (match_extension) + patlen = strlen (pattern) + else { + # Convert file matching pattern into general pattern string. + Memc[fname] = '^' + op = fname + 1 + lastch = 0 + for (ip=1; pattern[ip] != EOS; ip=ip+1) { + if (pattern[ip] == '*' && lastch != '?' && lastch != ']') { + Memc[op] = '?' + op = op + 1 + } + lastch = pattern[ip] + Memc[op] = lastch + op = op + 1 + } + Memc[op] = '$' + op = op + 1 + Memc[op] = EOS + + # Compile the pattern. + patlen = patmake (pattern, Memc[patbuf], SZ_LINE) + } + } + + # Initialize counters. + ndirs = 0 + nfiles = 0 + dp = NULL + fp = NULL + + # Accumulate the contents into the directory and files lists. We + # match files against the given template, all directories are + # matched regardless. + for (n=0; n != EOF; ) { + n = getline (dd, Memc[fname]) + if (n < 1) + break + n = n - 1 + Memc[fname+n] = EOS # stomp the newline + + # See if this is a directory. + call sprintf (Memc[path], SZ_PATHNAME, "%s%s") + call pargstr (CURDIR(xh)) + call pargstr (Memc[fname]) + if (xh_isdir (Memc[path], Memc[path], SZ_PATHNAME) > 0) { + ndirs = ndirs + 1 + + # If this is the first directory initialize the symbol table. + if (ndirs == 1) + dp = stopen ("dirlist", LEN_INDEX, LEN_STAB, SZ_SBUF) + + # Enter the directory name into the symbol table. + call strcat ("/", Memc[fname], SZ_FNAME) + sym = stenter (dp, Memc[fname], strlen(Memc[fname])+1) + + } else { + # Check if the file matches the given pattern. + if (patlen > 0) { + if (match_extension) { + if (n < patlen) + next + ep = fname + n - 1 + for (ip=patlen; ip > 2; ip=ip-1) { + if (Memc[ep] != pattern[ip]) + break + ep = ep - 1 + } + if (pattern[ip] != '.' || Memc[ep] != '.') + next + } else if (patmatch (Memc[fname], Memc[patbuf]) <= 0) + next + } + + # We have a match. + nfiles = nfiles + 1 + + # If this is the first file initialize the symbol table. + if (nfiles == 1) + fp = stopen ("filelist", LEN_INDEX, LEN_STAB, SZ_SBUF) + + # Enter the directory name into the symbol table. + sym = stenter (fp, Memc[fname], strlen(Memc[fname])+1) + } + } + + # Send the results to the GUI. + call xh_putlist (xh, dp, "directory", "dirlist") + call xh_putlist (xh, fp, "directory", "filelist") + + # Clean up. + if (dp != NULL) + call stclose (dp) + if (fp != NULL) + call stclose (fp) + call close (dd) + call sfree (sp) +end + + +# XH_PUTLIST -- Given the symtab for the directory contents construct a +# list suitable for a message to the GUI. The 'arg' parameter is passed +# to indicate which type of list this is. + +procedure xh_putlist (xh, stp, param, arg) + +pointer xh #i task descriptor +pointer stp #i symtab ptr for list +char param[ARB] #i GUI param to notify +char arg[ARB] #i GUI param arg + +pointer sp, list, msg, sym, name, ip +int nchars + +pointer sthead(), stnext(), stname() +int stsize(), gstrcpy(), strcmp(), strlen() + +begin + # Return if there is no symtab information. + if (stp == NULL) { + call smark (sp) + call salloc (msg, SZ_FNAME , TY_CHAR) + call sprintf (Memc[msg], SZ_FNAME, "%s { }") + call pargstr (arg) + + call gmsg (XH_GP(xh), param, Memc[msg]) # send it to the GUI + call gflush (XH_GP(xh)) + call sfree (sp) + return + } + + # Allocate space for the list. + nchars = stsize (stp) + 1 + + call smark (sp) + call salloc (list, nchars , TY_CHAR) + call aclrc (Memc[list], nchars) + ip = list + + # Build the list from the symtab. + for (sym = sthead (stp); sym != NULL; sym = stnext (stp,sym)) { + name = stname(stp,sym) + if (strcmp (Memc[name], "./") != 0) { + ip = ip + gstrcpy (Memc[name], Memc[ip], SZ_FNAME) + ip = ip + gstrcpy (" ", Memc[ip], SZ_FNAME) + } + } + + # Sort the list. + call xh_sort_list (Memc[list]) + + # Allocate space for the message buffer. The "+ 6" is space for + # the brackets around the list in the message created below. + nchars = nchars + strlen (arg) + 6 + call salloc (msg, nchars, TY_CHAR) + call aclrc (Memc[msg], nchars) + ip = msg + + # Begin the message by adding the arg and make a Tcl list of the + # contents. + call sprintf (Memc[msg], nchars, "%s { ") + call pargstr (arg) + call strcat (Memc[list], Memc[msg], nchars) + call strcat (" }", Memc[msg], nchars) + + # Finally, send it to the GUI. + call gmsg (XH_GP(xh), param, Memc[msg]) + call gflush (XH_GP(xh)) + + call sfree (sp) +end + + +# XH_LDFILE -- Load the requested file. If this is a file display it's +# contents and update the browser with it's directory, otherwise if it's +# a directory jump the browser to that directory. + +procedure xh_ldfile (xh, file) + +pointer xh #i task descriptor +char file[ARB] #i requested file/dir + +pointer sp, ip, dir, parent, path +int nchars +int access(), strlen(), xh_isdir() + +begin + call smark (sp) + call salloc (dir, SZ_PATHNAME, TY_CHAR) + call salloc (path, SZ_PATHNAME, TY_CHAR) + call salloc (parent, SZ_PATHNAME, TY_CHAR) + + # Expand the current directory to a host path. + call fdirname (file, Memc[dir], SZ_PATHNAME) + + if (xh_isdir (Memc[dir], Memc[path], SZ_PATHNAME) > 0) { + # Set the curdir and load it's contents. + call xh_set_curdir (xh, Memc[path]) + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + call xh_selection (xh, Memc[path]) + } + + if (access(file,0,0) == YES && + xh_isdir (file, Memc[path], SZ_PATHNAME) == 0) { + # Work backwards to the parent '/', be sure to skip the trailing + # backslash already in the dirname. + ip = dir + strlen (Memc[dir]) - 2 + while (Memc[ip] != '/' && ip > dir) + ip = ip - 1 + + nchars = ip - dir + if (nchars > 0) + call strcpy (Memc[dir], Memc[parent], nchars) + else + call strcpy ("/", Memc[parent], nchars) + + # Set the parent dir and load it's contents. + call xh_set_curdir (xh, Memc[parent]) + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + + # Now load the file itself. + call xh_open_file (xh, "helpres", file, YES, YES) + call xh_selection (xh, file) + } + + call sfree (sp) +end + + +# XH_UPDIR -- Go up to the parent directory and return contents. + +procedure xh_updir (xh) + +pointer xh #i task descriptor + +pointer sp, ip, dir, parent +int nchars, strlen() + +begin + call smark (sp) + call salloc (dir, SZ_PATHNAME, TY_CHAR) + call salloc (parent, SZ_PATHNAME, TY_CHAR) + + # Expand the current directory to a host path. + call fdirname (CURDIR(xh), Memc[dir], SZ_PATHNAME) + + # Work backwards to the parent '/', be sure to skip the trailing + # backslash already in the dirname. + ip = dir + strlen (Memc[dir]) - 2 + while (Memc[ip] != '/' && ip > dir) + ip = ip - 1 + + nchars = ip - dir + if (nchars > 0) + call strcpy (Memc[dir], Memc[parent], nchars) + else + call strcpy ("/", Memc[parent], nchars) + + # Set the parent dir and load it's contents. + call xh_set_curdir (xh, Memc[parent]) + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + call xh_selection (xh, CURDIR(xh)) + + call sfree (sp) +end + + +# XH_SET_CURDIR -- Set the filename matching template pattern. + +procedure xh_set_curdir (xh, dir) + +pointer xh #i task descriptor +char dir[ARB] #i current directory + +pointer sp, dirbuf +int strlen() + +begin + call smark (sp) + call salloc (dirbuf, SZ_PATHNAME, TY_CHAR) + + call strcpy (dir, CURDIR(xh), SZ_PATHNAME) + if (dir[strlen(dir)] != '/') + call strcat ("/", CURDIR(xh), SZ_PATHNAME) + + call sprintf (Memc[dirbuf], SZ_PATHNAME, "curdir %s") + call pargstr (CURDIR(xh)) + + call gmsg (XH_GP(xh), "directory", Memc[dirbuf]) + call gflush (XH_GP(xh)) + + call sfree (sp) +end + + +# XH_SET_PATTERN -- Set the filename matching template pattern. + +procedure xh_set_pattern (xh, pattern) + +pointer xh #i task descriptor +char pattern[ARB] #i template pattern + +pointer sp, patbuf + +begin + call smark (sp) + call salloc (patbuf, SZ_FNAME, TY_CHAR) + + call sprintf (Memc[patbuf], SZ_FNAME, "template %s") + call pargstr (pattern) + + call strcpy (pattern, PATTERN(xh), SZ_FNAME) + call gmsg (XH_GP(xh), "directory", Memc[patbuf]) + call gflush (XH_GP(xh)) + + call sfree (sp) +end + + +# XH_SELECTION -- Set the selected filename. + +procedure xh_selection (xh, selection) + +pointer xh #i task descriptor +char selection[ARB] #i selection + +pointer sp, buf + +begin + call smark (sp) + call salloc (buf, SZ_FNAME, TY_CHAR) + + call sprintf (Memc[buf], SZ_FNAME, "selection %s") + call pargstr (selection) + + call gmsg (XH_GP(xh), "directory", Memc[buf]) + call gflush (XH_GP(xh)) + call sfree (sp) +end + + +# XH_ISDIR -- Test whether the named file is a directory. Check first to +# see if it is a subdirectory of the current directory. If VFN is a directory, +# return the OS pathname of the directory in pathname, and the number of +# chars in the pathname as the function value. Otherwise return 0. + +int procedure xh_isdir (vfn, pathname, maxch) + +char vfn[ARB] # name to be tested +char pathname[ARB] # receives path of directory +int maxch # max chars out + +bool isdir +pointer sp, fname, op +int ip, fd, nchars, ch +long file_info[LEN_FINFO] +int finfo(), diropen(), gstrcpy(), strlen() + +begin + call smark (sp) + call salloc (fname, SZ_PATHNAME, TY_CHAR) + + # Copy the VFN string, minus any whitespace on either end. + op = fname + for (ip=1; vfn[ip] != EOS; ip=ip+1) { + ch = vfn[ip] + if (!IS_WHITE (ch)) { + Memc[op] = ch + op = op + 1 + } + } + Memc[op] = EOS + + isdir = false + if (finfo (Memc[fname], file_info) != ERR) { + isdir = (FI_TYPE(file_info) == FI_DIRECTORY) + + if (isdir) { + call fdirname (Memc[fname], pathname, maxch) + nchars = strlen (pathname) + } + + } else { + # If we get here, the VFN is the name of a new file. + ifnoerr (fd = diropen (Memc[fname], 0)) { + call close (fd) + isdir = true + } + nchars = gstrcpy (Memc[fname], pathname, maxch) + } + + call sfree (sp) + if (isdir) + return (nchars) + else { + pathname[1] = EOS + return (0) + } +end diff --git a/pkg/system/help/xhelp/xhelp.h b/pkg/system/help/xhelp/xhelp.h new file mode 100644 index 00000000..24bffc71 --- /dev/null +++ b/pkg/system/help/xhelp/xhelp.h @@ -0,0 +1,89 @@ +# XHELP.H -- Include file for the XHELP GUI task. + +# Help database header structure. Stored at the beginning of a help +# database file. This information is taken from the help$helpdb.x source. + +define LEN_HDBHEADER 14 +define HDB_MAGICVAL 110104B + +define HDB_MAGIC Memi[$1] # helpdb file type code +define HDB_RAW Memi[$1+1] # access compiled or raw database +define HDB_RHD Memi[$1+2] # if raw, HP of root help directory +define HDB_INDEX Memi[$1+3] # index of root help directory +define HDB_CRDATE Meml[$1+4] # creation date +define HDB_NENTRIES Memi[$1+5] # number of help directories in db +define HDB_MAXENTRIES Memi[$1+6] # maximum no. of help directories in db +define HDB_NMODULES Memi[$1+7] # count of the total number of modules +define HDB_INDEXOFFSET Meml[$1+8] # file offset of index, chars +define HDB_INDEXPTR Memi[$1+9] # pointer to loaded index, ty_struct +define HDB_INDEXLEN Memi[$1+10] # length of index structure, su +define HDB_DATAOFFSET Meml[$1+11] # file offset of data area, chars +define HDB_DATAPTR Memi[$1+12] # pointer to loaded data area, ty_struct +define HDB_DATALEN Memi[$1+13] # length of data area, struct units + +# Index structure. Identifies the contents of the database and tells where +# they are stored. There is one index entry for each help directory, i.e., +# for each package. + +define LEN_HDBINDEX 34 +define SZ_DBIKEY 63 +define LEN_DBIDATA 2 + +define DBI_KEY Memc[P2C($1)] # entry name +define DBI_OFFSET Memi[$1+32] # offset of entry into data area, su +define DBI_MTIME Meml[$1+33] # modification date of entry + +define MAX_ENTRIES 100 # initial max db entries +define INC_ENTRIES 50 # increment if overflow +define MAX_DEPTH 20 # max nesting of packages +define MAX_MENUSIZE 500 # max modules in a table +define MAX_NAMELEN 20 # max chars in a module name in table + + +# XHELP Macro definitions. +define SZ_HELPLIST 20480 +define SZ_XHELPSTRUCT 45 + +define XH_GP Memi[$1] # graphics descriptor +define XH_LPTR Memi[$1+1] # ptr for pkg list +define XH_TEMPLATE Memi[$1+2] # initial help topic +define XH_OPTION Memi[$1+3] # help option +define XH_PRINTER Memi[$1+4] # printer name +define XH_CURTASK Memi[$1+5] # current task name +define XH_CURPACK Memi[$1+6] # current package name +define XH_QUICKREF Memi[$1+7] # quick-reference filen +define XH_HOMEPAGE Memi[$1+8] # startup page +define XH_CURDIR Memi[$1+9] # current directory +define XH_PATTERN Memi[$1+10] # current filename template +define XH_HELPDB Memi[$1+11] # help database string +define XH_SHOWTYPE Memi[$1+12] # indicate packages in list +define XH_STP Memi[$1+13] # package list symtab ptr + +# Helpful macros +define LIST Memc[XH_LPTR($1)] +define TEMPLATE Memc[XH_TEMPLATE($1)] +define OPTION Memc[XH_OPTION($1)] +define PRINTER Memc[XH_PRINTER($1)] +define CURTASK Memc[XH_CURTASK($1)] +define CURPACK Memc[XH_CURPACK($1)] +define QUICKREF Memc[XH_QUICKREF($1)] +define HOMEPAGE Memc[XH_HOMEPAGE($1)] +define CURDIR Memc[XH_CURDIR($1)] +define PATTERN Memc[XH_PATTERN($1)] +define HELPDB Memc[XH_HELPDB($1)] + +define WIDE_PAGE 100 # needed by the print routines +define SZ_DDSTR 256 + + +# Filenames. +define HELP "lib$scr/help.html" # default help file +define PKGFILE "uparm$help.pkgs" # default package list symtab +define QREFFILE "uparm$quick.ref" # default references file + + +# Symbol table definitions. +define LEN_INDEX 10 # length of symtab index +define LEN_STAB 32 # initial length of symtab +define SZ_SBUF 32 # initial size of symtab string buffer + diff --git a/pkg/system/help/xhelp/xhelp.x b/pkg/system/help/xhelp/xhelp.x new file mode 100644 index 00000000..95a2f250 --- /dev/null +++ b/pkg/system/help/xhelp/xhelp.x @@ -0,0 +1,167 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <syserr.h> +include "../help.h" +include "xhelp.h" + + +# XHELP -- The main task procedure. XHELP is a GUI client program for +# browsing the IRAF help system. As much as possible it uses the existing +# help database code but provides a friendlier interface, allowing users to +# browse packages for help pages in the same way they would browse packages +# in the CL. It provides an HTML converter for LROFF sources for better +# presentation in the GUI, as well as Postscript generation for better +# looking hardcopy. XHelp acts as a server for the help system, merely +# returning any output that the GUI has requested. Navigation is done in +# the GUI code, this program maintains just the state of the last page +# returned and knows nothing about how it got there. See the xhelp.hlp for +# detailed documentation. + +procedure xhelp (topic) + +char topic[ARB] #I help template + +pointer xh +char uifname[SZ_FNAME] +int search, template + +pointer xh_open(), gopenui() +bool clgetb() +int btoi() + +begin + # Open structure and allocate pointers. + xh = xh_open () + call strcpy (topic, TEMPLATE(xh), SZ_FNAME) + + # Load the task parameters. + call clgstr ("option", OPTION(xh), SZ_FNAME) + call clgstr ("printer", PRINTER(xh), SZ_FNAME) + call clgstr ("quickref", QUICKREF(xh), SZ_FNAME) + XH_SHOWTYPE(xh) = btoi (clgetb("showtype")) + search = btoi (clgetb("search")) + template = btoi (clgetb("file_template")) + + # Fetch the name of the help database. + call xh_ghelpdb (xh) + + # Open the GUI. + call clgstr ("uifname", uifname, SZ_FNAME) + XH_GP(xh) = gopenui ("stdgraph", NEW_FILE, uifname, STDGRAPH) + call gflush (XH_GP(xh)) + + # Initialize the task and send topic list to the GUI. + call xh_init (xh, template, search) + + # Initialize the task and send topic list to the GUI. + call xh_command_loop (xh) + + # Clean up. + call gclose (XH_GP(xh)) + call xh_close (xh) +end + + +# XH_OPEN -- Open and allocate the XHELP task structure. + +pointer procedure xh_open () + +pointer xh # task descriptor +errchk calloc + +begin + iferr (call calloc (xh, SZ_XHELPSTRUCT, TY_STRUCT)) + call error (0, "Error opening task structure.") + + iferr { + call calloc (XH_LPTR(xh), SZ_HELPLIST, TY_CHAR) + call calloc (XH_TEMPLATE(xh), SZ_FNAME, TY_CHAR) + call calloc (XH_OPTION(xh), SZ_FNAME, TY_CHAR) + call calloc (XH_PRINTER(xh), SZ_FNAME, TY_CHAR) + call calloc (XH_CURTASK(xh), SZ_FNAME, TY_CHAR) + call calloc (XH_CURPACK(xh), SZ_FNAME, TY_CHAR) + call calloc (XH_QUICKREF(xh), SZ_FNAME, TY_CHAR) + call calloc (XH_HOMEPAGE(xh), SZ_FNAME, TY_CHAR) + call calloc (XH_CURDIR(xh), SZ_PATHNAME, TY_CHAR) + call calloc (XH_PATTERN(xh), SZ_FNAME, TY_CHAR) + call calloc (XH_HELPDB(xh), SZ_HELPDB, TY_CHAR) + } then + call error (0, "Error allocating structure pointers.") + + return (xh) +end + + +# XH_CLOSE -- Close the XHELP task structure. + +procedure xh_close (xh) + +pointer xh # task descriptor + +begin + call mfree (XH_TEMPLATE(xh), TY_CHAR) + call mfree (XH_OPTION(xh), TY_CHAR) + call mfree (XH_PRINTER(xh), TY_CHAR) + call mfree (XH_CURTASK(xh), TY_CHAR) + call mfree (XH_CURPACK(xh), TY_CHAR) + call mfree (XH_QUICKREF(xh), TY_CHAR) + call mfree (XH_HOMEPAGE(xh), TY_CHAR) + call mfree (XH_CURDIR(xh), TY_CHAR) + call mfree (XH_PATTERN(xh), TY_CHAR) + call mfree (XH_HELPDB(xh), TY_CHAR) + call mfree (XH_LPTR(xh), TY_CHAR) + + call mfree (xh, TY_STRUCT) +end + + +# XH_GHELPDB -- Fetch the name of the help database, i.e., "helpdb", +# "helpdir", or the name of a file. If the helpdb string is a list check +# for the existance of each file in the list to ensure the final list +# contains only valid help databases. + +procedure xh_ghelpdb (xh) + +pointer xh # task descriptor + +pointer sp, hdb, hdbstr, name +int list +int fntopnb(), fntgfnb() +int access(), envgets() +bool streq() + +begin + call smark (sp) + call salloc (name, SZ_FNAME, TY_CHAR) + call salloc (hdb, SZ_HELPDB, TY_CHAR) + call salloc (hdbstr, SZ_HELPDB, TY_CHAR) + + # Clear the working memory. + call aclrc (Memc[name], SZ_FNAME) + call aclrc (Memc[hdb], SZ_HELPDB) + call aclrc (Memc[hdbstr], SZ_HELPDB) + + # Get the parameter value. + call clgstr ("helpdb", Memc[hdbstr], SZ_HELPDB) + if (streq (Memc[hdbstr], "helpdb")) + if (envgets ("helpdb", Memc[hdbstr], SZ_HELPDB) <= 0) + call syserrs (SYS_ENVNF, "helpdb") + + # Open the list. + list = fntopnb (Memc[hdbstr], YES) + + # Copy each of the existing files in the list to the output database + # string to be used by the task. + while (fntgfnb(list, Memc[name], SZ_FNAME) != EOF) { + if (access (Memc[name], 0, 0) == YES) { + if (Memc[hdb] != EOS) + call strcat (",", Memc[hdb], SZ_HELPDB) + call strcat (Memc[name], Memc[hdb], SZ_HELPDB) + } + } + call strcpy (Memc[hdb], HELPDB(xh), SZ_HELPDB) + + # Clean up. + call fntclsb (list) + call sfree (sp) +end diff --git a/pkg/system/help/xhelp/xhfiles.x b/pkg/system/help/xhelp/xhfiles.x new file mode 100644 index 00000000..53597eda --- /dev/null +++ b/pkg/system/help/xhelp/xhfiles.x @@ -0,0 +1,89 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fset.h> +include <ctype.h> +include "../help.h" +include "xhelp.h" + + +# XH_FILES -- Get the files associated with the requested help topic, +# i.e. do a "help <topic> opt=files" request. + +procedure xh_files (xh, topic, curpack) + +pointer xh #i task struct pointer +char topic[ARB] #i help topic +char curpack[ARB] #i current package + +pointer sp, bp, buf +pointer opt, val, line +int fd +long fsize +char fname[SZ_FNAME] + +long fstatl() +int getline(), access(), open(), stridxs(), strlen() + +begin + if (topic[1] == EOS && curpack[1] == EOS) + return + + call smark (sp) + call salloc (line, SZ_LINE, TY_CHAR) + call salloc (buf, SZ_FNAME, TY_CHAR) + call salloc (opt, SZ_FNAME, TY_CHAR) + call salloc (val, SZ_FNAME, TY_CHAR) + + # Get a temp file name. + call mktemp ("tmp$xhelpi", fname, SZ_FNAME) + + # Open a temp file with the help information found. + fd = open (fname, NEW_FILE, TEXT_FILE) + call xh_get_help (fd, topic, curpack, "", HF_HTML, HELPDB(xh), + "all", "files") + call close (fd) + + # Open the results file for reading. + fd = open (fname, READ_ONLY, TEXT_FILE) + fsize = fstatl (fd, F_FILESIZE) + + # If we got a result parse the lines for "opt=file" information. + if (fsize != 0) { + + while (getline (fd, Memc[line]) != EOF) { + + # Stomp the newline. + Memc[line+strlen(Memc[line])-1] = EOS + + # Extract the option type and filename. + if (stridxs ("=", Memc[line]) > 0) { + for (bp=line; IS_WHITE(Memc[bp]); bp=bp+1) + ; + call strcpy (Memc[bp], Memc[opt], 3) + for (; Memc[bp] != '='; bp=bp+1) + ; + call strcpy (Memc[bp+1], Memc[val], SZ_FNAME) + + # See if the file exists. + call sprintf (Memc[buf], SZ_FNAME, "%s %s \0") + call pargstr (Memc[opt]) + call pargstr (Memc[val]) + if (access (Memc[val],0,0) == YES) + call strcat (" 0", Memc[buf], SZ_FNAME) + else + call strcat (" 1", Memc[buf], SZ_FNAME) + call gmsg (XH_GP(xh), "helpfiles", Memc[buf]) + + } else if (stridxs (":", Memc[line]) > 0) { + call xh_pkgpath (xh, topic, curpack, Memc[line]) + call sprintf (Memc[buf], SZ_FNAME, "file %s") + call pargstr (Memc[line]) + call gmsg (XH_GP(xh), "helpfiles", Memc[buf]) + } + } + } + + call close (fd) # clean up + call delete (fname) + call sfree (sp) +end diff --git a/pkg/system/help/xhelp/xhhelp.x b/pkg/system/help/xhelp/xhhelp.x new file mode 100644 index 00000000..708a00ce --- /dev/null +++ b/pkg/system/help/xhelp/xhhelp.x @@ -0,0 +1,276 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fset.h> +include <finfo.h> +include <error.h> +include "../help.h" +include "xhelp.h" + + +# XH_HELP -- Get the requested help topic and send the result to the GUI. + +procedure xh_help (xh, topic, curpack, opt) + +pointer xh #i task struct pointer +char topic[ARB] #i help topic +char curpack[ARB] #i current package +char opt[ARB] #i help option + +pointer helpstr +int ip, fdi +long fsize +char ch, fname[SZ_FNAME], err[SZ_LINE] + +long fstatl() +char getc() +int open() +bool strne() + +begin + # Get a temp file name. + call mktemp ("tmp$xhelpi", fname, SZ_FNAME) + + # Open a temp file with the help information found. + fdi = open (fname, NEW_FILE, TEXT_FILE) + call xh_get_help (fdi, topic, curpack, "", HF_HTML, HELPDB(xh), + "all", opt) + call close (fdi) + + # Open the results file for reading. + fdi = open (fname, READ_ONLY, TEXT_FILE) + fsize = fstatl (fdi, F_FILESIZE) + + # If no results try using the topic name as a curpack param. + if (fsize == 0) { + call close (fdi) # clean up from before + call delete (fname) + + # Open a temp file with the help information found. + fdi = open (fname, NEW_FILE, TEXT_FILE) + call xh_get_help (fdi, topic, topic, "", HF_HTML, HELPDB(xh), + "all", opt) + call close (fdi) + + # Open the results file for reading. + fdi = open (fname, READ_ONLY, TEXT_FILE) + fsize = fstatl (fdi, F_FILESIZE) + + # If we still have nothing then punt... + if (fsize == 0 && topic[1] != EOS) { + if (strne (opt, "help")) { + call sprintf (err, SZ_LINE, + "No '%s' option help available\n for `%s'.") + call pargstr (opt) + call pargstr (topic) + } else { + call sprintf (err, SZ_LINE, "No help available for\n`%s'.") + call pargstr (topic) + } + call gmsg (XH_GP(xh), "alert", err) + call close (fdi) + call delete (fname) + return + } + } + + # Now filter the file to escape the curly braces so they pass thru + # to the Tcl cleanly. Put the result in the string sent to the GUI. + call calloc (helpstr, fsize + SZ_LINE, TY_CHAR) + ip = helpstr + repeat { + ch = getc (fdi, ch) + if (ch == '{' || ch == '}') { + Memc[ip] = '\\' + ip = ip + 1 + } + Memc[ip] = ch + ip = ip + 1 + } until (ch == EOF) + Memc[ip-1] = EOS + + # Clean up. + call close (fdi) + call delete (fname) + + # Send the help text to the GUI who will display it. + call gmsg (XH_GP(xh), "helpres", Memc[helpstr]) + call mfree (helpstr, TY_CHAR) +end + + +# XH_GET_HELP -- The main work procedure, i.e. a rip-off of the t_help() +# procedure. Decode the option string, set up the control structure, and +# finally call process_template to expand the module template and process +# the help text for each module. The output is written to a temp file +# opened by the calling procedure which may optionally sort it or display +# it as is. + +procedure xh_get_help (fd, topic, curpack, file, format, helpdb, section, opt) + +int fd #i file descriptor of result +char topic[ARB] #i topic +char curpack[ARB] #i current package +char file[ARB] #i file template +int format #i output format (text|html|ps) +char helpdb[ARB] #i help database +char section[ARB] #i section on which to get help +char opt[ARB] #i type of help + +int list +long fi[LEN_FINFO], db_ctime +pointer sp, ctrl, optn, db, fname + +long clktime() +pointer hdb_open() +bool strne(), streq() +int stridxs(), finfo(), fntopnb(), fntgfnb(), get_option() + +errchk hdb_open + +data db_ctime /0/ +define forms_ 91 + +begin + call smark (sp) + call salloc (ctrl, LEN_CTRLSTRUCT, TY_STRUCT) + call salloc (optn, SZ_FNAME, TY_CHAR) + call salloc (fname, SZ_PATHNAME, TY_CHAR) + + # If we were called without any arguments, do not query for the + # template, just set it to null and help will be given for the + # current package. + + call aclri (Memi[ctrl], LEN_CTRLSTRUCT) + if (topic[1] == EOS) { + if (file[1] == EOS) { + H_OPTION(ctrl) = O_MENU + H_TEMPLATE(ctrl) = EOS + H_PARNAME(ctrl) = EOS + H_SECNAME(ctrl) = EOS + } else + call strcpy (file, H_TEMPLATE(ctrl), SZ_LINE) + } else { + call strcpy (topic, H_TEMPLATE(ctrl), SZ_LINE) + } + + + # Check to see if any of the files in the list are newer than the + # time of the last hdb_open. The first time the process runs we open + # and read in the database. The database remains in memory between + # calls to HELP, provided the process does not shutdown, provided + # the name of the database to be used does not change, and provided + # a new help database is not created. + + if (db_ctime > 0) { + list = fntopnb (helpdb, YES) + while (fntgfnb (list, Memc[fname], SZ_PATHNAME) != EOF) { + if (finfo (Memc[fname], fi) != ERR) { + if (db != NULL && FI_CTIME(fi) > db_ctime) { + call hdb_close (db) + db = NULL + break + } + } + } + call fntclsb (list) + } else + db = NULL + + # Reopen the help database if in-core copy is out of date. + if (db == NULL) { + db = hdb_open (helpdb) + db_ctime = clktime (long(0)) + } + + # Fetch the value of the ALL switch. This determines whether help + # will stop after processing the first module matching the template, + # or process all modules in the database which match the template. + # Explicit use of a pattern matching character anywhere in the template + # enable allmodoules. + + if (stridxs ("*?[],", H_TEMPLATE(ctrl)) > 0) + H_ALLMODULES(ctrl) = YES + else + H_ALLMODULES(ctrl) = NO + + # If the FILTER_INPUT flag is set, only part of the input text will be + # processed. Filtering is only done if printing a single section or + # parameter. + + H_FILTER_INPUT(ctrl) = NO + + # Determine whether or not text for a single section or parameter + # is to be output. If the value of one of these strings is "all", + # all sections or all parameters are to be output. If the "all" + # default is in effect, null the string as a flag to lower level + # code that all help text is to be processed. + + if (H_OPTION(ctrl) == NULL) { + call strcpy (section, H_SECNAME(ctrl), SZ_SECNAME) + if (streq (H_SECNAME(ctrl), "all")) { + H_SECNAME(ctrl) = EOS + H_PARNAME(ctrl) = EOS + } + if (H_SECNAME(ctrl) != EOS || H_PARNAME(ctrl) != EOS) + H_FILTER_INPUT(ctrl) = YES + } + + # Fetch and decode option string; abbreviations are permitted. + if (H_OPTION(ctrl) != O_MENU) { + call strcpy (opt, Memc[optn], SZ_FNAME) + call strlwr (Memc[optn]) + iferr (H_OPTION(ctrl) = get_option (Memc[optn])) { + H_OPTION(ctrl) = O_HELP + call erract (EA_WARN) + } + } + +forms_ + # Pause between screens of output text only if the standard output + # is not redirected, and if enabled by the user. + + H_IN(ctrl) = ERR + H_OUT(ctrl) = fd + H_NLINES(ctrl) = -1 + H_STATE(ctrl) = BOF + H_EOF(ctrl) = NO + H_QUIT(ctrl) = NO + + # If the standard output is not redirected, i.e., if writing to the + # terminal, determine whether or not output is to be paginated (pause + # between pages). If output is redirected, the pagination flag + # and help option controls whether or not manpage style output is + # enabled. Manpage output formatting is desirable only when formatting + # help text or printing named files. + + H_RAWOUT(ctrl) = YES + H_MANPAGE(ctrl) = NO + H_PAGINATE(ctrl) = NO + H_SOFLAG(ctrl) = NO + H_FORMAT(ctrl) = format + + # We don't produce output to a screen so shut off the tty. + + H_TTY(ctrl) = NULL + + # Set left and right margins for output text format. + + H_LMARGIN(ctrl) = 1 + H_RMARGIN(ctrl) = 72 + + # Copy the current package to the control struct. + if (strne(curpack,"Home") && strne(curpack,"")) + call strcpy (curpack, H_CURPACK(ctrl), SZ_CURPACK) + + # Initialization is completed, control structure is completed. + # Format and output the help text. If we have a module name template + # process the template against the help database, otherwise work + # directly out of the named files. + + if (file[1] == EOS) + call do_module_template (db, H_TEMPLATE(ctrl), ctrl) + else + call do_file_template (H_TEMPLATE(ctrl), ctrl) + + call sfree (sp) +end diff --git a/pkg/system/help/xhelp/xhinit.x b/pkg/system/help/xhelp/xhinit.x new file mode 100644 index 00000000..41ff5b65 --- /dev/null +++ b/pkg/system/help/xhelp/xhinit.x @@ -0,0 +1,77 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "xhelp.h" + + +# XH_INIT -- Initialize the task and the GUI. + +procedure xh_init (xh, file_template, search) + +pointer xh #i task struct pointer +int file_template #i is topic a file template? +int search #i doing a search? + +char curdir[SZ_FNAME] +int fd + +pointer strestore() +int envgets(), open() +bool streq() +errchk open + +begin + # Update the quickref file. + call xh_updt_quickref (xh) + + # If starting up with a search, get that information first. + if (search == YES && TEMPLATE(xh) != EOS) { + call xh_search (xh, NO, TEMPLATE(xh)) + call strcpy ("", TEMPLATE(xh), SZ_FNAME) + call strcpy ("", LIST(xh), SZ_LINE) + } + + # Create the root package and send the results to the GUI. + call xh_root_pkg (xh) + call gmsg (XH_GP(xh), "pkglist", LIST(xh)) + + # Initialize the package list symtab. + iferr (fd = open (PKGFILE, READ_ONLY, BINARY_FILE)) + call error (0, "Cannot open package list symtab") + XH_STP(xh) = strestore (fd) + call close (fd) + call gmsgi (XH_GP(xh), "showtype", XH_SHOWTYPE(xh)) + + + if (TEMPLATE(xh) != EOS && file_template == NO) { + # If we're given an initial help topic, get the page and load it. + #call xh_help (xh, TEMPLATE(xh), TEMPLATE(xh), OPTION(xh)) + call xh_cmd_help (xh, TEMPLATE(xh), "{}", OPTION(xh)) + call strcpy ("", TEMPLATE(xh), SZ_FNAME) + + } else if (TEMPLATE(xh) != EOS && file_template == YES) { + # Load a user defined page. + call xh_open_file (xh, "helpres", TEMPLATE(xh), YES, YES) + call strcpy ("", TEMPLATE(xh), SZ_FNAME) + + } else { + # Load either a user defined homepage or the task help. + call clgstr ("home", HOMEPAGE(xh), SZ_FNAME) + if (streq ("", HOMEPAGE(xh))) + call strcpy (HELP, HOMEPAGE(xh), SZ_FNAME) + call xh_open_file (xh, "helpres", HOMEPAGE(xh), NO, YES) + } + + # Set the printer to be used. + call gmsg (XH_GP(xh), "printer", PRINTER(xh)) + + # Initialize the online help doc. + call xh_open_file (xh, "help", HELP, NO, YES) + + # Initialize the file browsing parameters. Since we can't + # get the current directory for the session use home$. + if (envgets ("home", curdir, SZ_FNAME) != EOF) { + call xh_set_pattern (xh, "*") + call xh_set_curdir (xh, curdir) + call xh_dirlist (xh, CURDIR(xh), PATTERN(xh)) + } +end diff --git a/pkg/system/help/xhelp/xhofile.x b/pkg/system/help/xhelp/xhofile.x new file mode 100644 index 00000000..c12ea7d3 --- /dev/null +++ b/pkg/system/help/xhelp/xhofile.x @@ -0,0 +1,188 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fset.h> +include "xhelp.h" + + +# XH_OPEN_FILE -- Open the named file and send it to the GUI. If this is +# a help document (i.e. it contains a ".help" block) we first convert it +# to HTML, otherwise send it as is. + +procedure xh_open_file (xh, parameter, filename, check_for_help, warn) + +pointer xh # task descriptor +char parameter[ARB] # GUI parameter to notify +char filename[ARB] # file to open +int check_for_help # check file for help block? +int warn # warn if not present? + +pointer sp, ip, buf, out, text +int fdi, fdo +long fsize +bool has_help + +int access(), open(), getline() +int strmatch(), gstrcpy() +long fstatl() +errchk open + +define err_ 99 + +begin + call smark (sp) + call salloc (buf, SZ_LINE, TY_CHAR) + call salloc (out, SZ_FNAME, TY_CHAR) + + # Make sure the file exists. + if (access (filename, 0, 0) == NO) { + if (warn == YES) { + call sprintf (Memc[buf], SZ_LINE, "File does not exist:\n`%s'.") + call pargstr (filename) + call gmsg (XH_GP(xh), "alert", Memc[buf]) + } + goto err_ + } else if (access (filename, 0, BINARY_FILE) == YES) { + if (warn == YES) { + call sprintf (Memc[buf], SZ_LINE, + "Attempt to load binary file:\n`%s'.") + call pargstr (filename) + call gmsg (XH_GP(xh), "alert", "pop") + call gmsg (XH_GP(xh), "alert", Memc[buf]) + } + goto err_ + } + + # If we're told not to look for help simply open the file and send + # it to the GUI (e.g. used for homepage and online help). + if (check_for_help == NO) { + call xh_load_file (xh, parameter, filename) + call sfree (sp) + return + } + + # Open the file. + iferr (fdi = open (filename, READ_ONLY, TEXT_FILE)) { + if (warn == YES) { + call sprintf (Memc[buf], SZ_LINE, "Cannot open file\n`%s'.") + call pargstr (filename) + call gmsg (XH_GP(xh), "alert", Memc[buf]) + } + goto err_ + } + + # Allocate an array the length of the file, if this isn't a help file + # we use this as the message buffer and send it to the GUI. + fsize = fstatl (fdi, F_FILESIZE) + call salloc (text, fsize+1, TY_CHAR) + call aclrc (Memc[text], fsize+1) + + # See whether this is a help file + has_help = FALSE + ip = text + while (getline (fdi, Memc[buf]) != EOF) { + if (strmatch (Memc[buf], "^.help") > 0) { + has_help = TRUE + break + } + ip = ip + gstrcpy (Memc[buf], Memc[ip], SZ_LINE) + } + Memc[ip] = EOS + + + # If the file was found to have a .help block we're positioned at + # the beginning of the block. Convert the remainder to an HTML + # temp file and send that to the GUI, otherwise we already have the + # contents of the file in the text buffer so send that. + if (has_help) { + # Create an output filename and open it for writing. + call mktemp ("tmp$xhelpi", Memc[out], SZ_FNAME) + fdo = open (Memc[out], NEW_FILE, TEXT_FILE) + + # Convert the remainder to HTML and send it to the GUI. + if (fdo != ERR) { + call lroff2html (fdi, fdo, filename, "", "", "", "") + call close (fdo) + + call xh_load_file (xh, "helpres", Memc[out]) + call delete (Memc[out]) + } + + } else { + # No help was found, send the contents straight to the display. + call xh_text_msg (XH_GP(xh), "helpres", Memc[text]) + } + + +err_ if (fdi != ERR) + call close (fdi) + call sfree (sp) +end + + +# XH_LOAD_FILE -- Load the named file in the GUI. + +procedure xh_load_file (xh, parameter, filename) + +pointer xh # task descriptor +char parameter[ARB] # GUI parameter to notify +char filename[ARB] # file to display + +pointer sp, ip, line, text +int fd, open(), getline(), gstrcpy() +long fsize, fstatl() +errchk open + +begin + call smark (sp) + call salloc (line, SZ_LINE, TY_CHAR) + + # Open the file and send it to the display. + fd = open (filename, READ_ONLY, TEXT_FILE) + if (fd != ERR) { + fsize = fstatl (fd, F_FILESIZE) + call salloc (text, fsize+1, TY_CHAR) + call aclrc (Memc[text], fsize+1) + + for (ip=text; getline (fd, Memc[line]) != EOF; ) + ip = ip + gstrcpy (Memc[line], Memc[ip], SZ_LINE) + + Memc[ip] = EOS + call close (fd) + + call xh_text_msg (XH_GP(xh), parameter, Memc[text]) + } + + call sfree (sp) +end + + +# XH_TEXT_MSG -- Send a text message to a named UI parameter but first +# escape all curly braces so it passes through the Tcl correctly. + +procedure xh_text_msg (gp, param, msg) + +pointer gp +char param[ARB], msg[ARB] + +pointer buf, ip +int i, nchars +int strlen() + +begin + nchars = strlen (msg) + call calloc (buf, nchars + SZ_LINE, TY_CHAR) + + ip = buf + for (i=1; i < nchars; i=i+1) { + if (msg[i] == '{' || msg[i] == '}') { + Memc[ip] = '\\' + ip = ip + 1 + } + Memc[ip] = msg[i] + ip = ip + 1 + } + + call gmsg (gp, "type", "file") + call gmsg (gp, param, Memc[buf]) + call mfree (buf, TY_CHAR) +end diff --git a/pkg/system/help/xhelp/xhpkg.x b/pkg/system/help/xhelp/xhpkg.x new file mode 100644 index 00000000..44580f15 --- /dev/null +++ b/pkg/system/help/xhelp/xhpkg.x @@ -0,0 +1,192 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fset.h> +include <error.h> +include "../help.h" +include "../helpdir.h" +include "xhelp.h" + + +# XH_GPKGLIST -- Get the requested package list as a sorted array of pointers. +# This is essentially a "help <pkg>" request, the caller passes the sorted +# list returned in 'pkglist" required. + +int procedure xh_pkglist (xh, topic, helpdb, pkglist) + +pointer xh #i task descriptor pointer +char topic[ARB] #i search key +char helpdb[ARB] #i filename of database to be examined +char pkglist[ARB] #o package list + +int i, m +pointer sp, pknm, hp, pp, sym +pointer db, ixoff, ix + +bool strne() +int gstrcpy(), strsearch(), hd_getname() +pointer hdb_open(), hdb_load(), stfind() +errchk hdb_open, hdb_printpack, hdb_load + +begin + call smark (sp) + call salloc (pknm, MAX_MENUSIZE, TY_POINTER) + + db = hdb_open (helpdb) + ixoff = HDB_INDEXPTR(db) + pp = NULL + + # Search for the right topic. + do i = 1, HDB_NENTRIES(db) { + ix = ixoff + (i - 1) * LEN_HDBINDEX + if (strne (DBI_KEY(ix), "_index") && + strsearch (DBI_KEY(ix),topic) != 0) { + + iferr (hp = hdb_load (db, DBI_KEY(ix))) { + call sfree (sp) + call erract (EA_WARN) + return (0) + } + + # If this isn't the package we're after then move on. + if (HD_PAKNAME(hp) == 0 || + strne (topic, Memc[HD_SBUF(hp)+HD_PAKNAME(hp)])) + next + + # Extract the names of the modules in the package. Save the + # pointers in an array for the table print routine. + + pp = 1 + for (m=0; m < MAX_MENUSIZE; m=m+1) { + call salloc (Memi[pknm+m], MAX_NAMELEN, TY_CHAR) + if (hd_getname (hp, m+1, TY_MODNAME, Memc[Memi[pknm+m]], + MAX_NAMELEN) <= 0) + break + + # Copy the names to the output array. + pp = pp + gstrcpy (Memc[Memi[pknm+m]], pkglist[pp], ARB) + if (XH_SHOWTYPE(xh) == YES && XH_STP(xh) != NULL) { + sym = stfind (XH_STP(xh), Memc[Memi[pknm+m]]) + if (sym != NULL) + pp = pp + gstrcpy (".", pkglist[pp], ARB) + } + pp = pp + gstrcpy (" ", pkglist[pp], ARB) + } + break + } + } + if (pp != NULL) + pkglist[pp] = EOS + + call hdb_free (db, hp) + call hdb_close (db) + call sfree (sp) + return (pp) +end + + +# XH_PKGPATH -- Get the package path associated with a particular task. +# If we're given a parent package follow it back so we get the correct +# path for a task that may be defined multiple places (e.g. SPLOT). + +procedure xh_pkgpath (xh, topic, curpack, path) + +pointer xh #i task struct pointer +char topic[ARB] #i help topic +char curpack[ARB] #i help topic +char path[ARB] #o package path + +pointer sp, pkg, task, buf +int strncmp(), xh_pkgname() +bool streq() + +begin + call smark (sp) + call salloc (pkg, SZ_FNAME, TY_CHAR) + call salloc (task, SZ_FNAME, TY_CHAR) + call salloc (buf, SZ_FNAME, TY_CHAR) + + if (curpack[1] == EOS || + streq (topic, curpack) || + strncmp ("root", curpack, 4) == 0 || + streq ("clpackage", curpack)) { + call strcpy (topic, Memc[task], SZ_FNAME) + call strcpy (topic, path, SZ_FNAME) + } else { + call strcpy (curpack, Memc[task], SZ_FNAME) + call sprintf (path, SZ_PATHNAME, "%s.%s") + call pargstr (curpack) + call pargstr (topic) + } + + Memc[pkg] = EOS + while (xh_pkgname (xh, Memc[task], Memc[pkg]) == OK) { + if (strncmp ("root", Memc[pkg], 4) == 0 || + streq (Memc[task], Memc[pkg]) || + streq ("clpackage", Memc[pkg])) + break + else { + call sprintf (Memc[buf], SZ_PATHNAME, "%s.%s") + call pargstr (Memc[pkg]) + call pargstr (path) + call strcpy (Memc[buf], path, SZ_PATHNAME) + } + call strcpy (Memc[pkg], Memc[task], SZ_FNAME) + Memc[pkg] = EOS + } + + call sfree (sp) +end + + +# XH_PKGNAME -- Get the package name associated with a particular task. + +int procedure xh_pkgname (xh, topic, pack) + +pointer xh #i task struct pointer +char topic[ARB] #i help topic +char pack[ARB] #o package + +pointer sp, line, fname +long fsize, fstatl() +int fd, status, getline(), open(), stridxs() + +begin + call smark (sp) + call salloc (line, SZ_LINE, TY_CHAR) + call salloc (fname, SZ_LINE, TY_CHAR) + + status = ERR + + # Get a temp file name. + call mktemp ("tmp$xhelpi", Memc[fname], SZ_FNAME) + + # Open a temp file with the help information found. + fd = open (Memc[fname], NEW_FILE, TEXT_FILE) + call xh_get_help (fd, topic, "", "", HF_HTML, HELPDB(xh), + "all", "files") + call close (fd) + + # Open the results file for reading. + fd = open (Memc[fname], READ_ONLY, TEXT_FILE) + fsize = fstatl (fd, F_FILESIZE) + + # Search the results for the package line. + if (fsize != 0) { + status = OK + while (getline (fd, Memc[line]) != EOF) { + + # Extract the package name. + if (stridxs (":", Memc[line]) > 0) { + Memc[line+stridxs(".",Memc[line])-1] = EOS + call strcpy (Memc[line], pack, SZ_FNAME) + break + } + } + } + + call close (fd) # clean up + call delete (Memc[fname]) + call sfree (sp) + + return (status) +end diff --git a/pkg/system/help/xhelp/xhprint.x b/pkg/system/help/xhelp/xhprint.x new file mode 100644 index 00000000..4e273848 --- /dev/null +++ b/pkg/system/help/xhelp/xhprint.x @@ -0,0 +1,151 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <syserr.h> +include <error.h> +include <ctype.h> +include <ttyset.h> +include "../help.h" +include "xhelp.h" + + +# XH_PRINT_HELP -- Print the requested help topic. + +procedure xh_print_help (xh, topic, curpack, name) + +pointer xh #i task struct pointer +char topic[ARB] #i help topic +char curpack[ARB] #i current package +char name[ARB] #i printer name + +int fd +char fname[SZ_FNAME] + +int open() +errchk open + +begin + # Open a temp file with the help information. + call mktemp ("tmp$xhelpi", fname, SZ_FNAME) + fd = open (fname, NEW_FILE, TEXT_FILE) + call xh_get_help (fd, topic, curpack, "", HF_PS, HELPDB(xh), + "all", OPTION(xh)) + call close (fd) + + call strcpy (name, PRINTER(xh), SZ_FNAME) + call xh_lprint (fname, PRINTER(xh)) + + # Clean up. + call delete (fname) +end + + +# XH_LPRINT -- Print a file or files on the lineprinter. TTYPUTLINE is used +# to output lines to the printer file, so that formfeeds, standout mode, etc., +# may be properly translated for the indicated device. + +procedure xh_lprint (fname, device) + +char fname[ARB] +char device[ARB] + +int out +pointer sp, lp, ddstr + +pointer ttyodes() +bool streq() +int envgets(), lpopen(), ttygets() +string printer "printer" +errchk clgfil, xh_print_file + +begin + call smark (sp) + call salloc (ddstr, SZ_DDSTR, TY_CHAR) + + # Get device name. Default is "printer", which means that the actual + # device name is given by the environment variable "printer". + + if (streq (device, printer)) + if (envgets (printer, device, SZ_FNAME) <= 0) + call syserrs (SYS_ENVNF, printer) + + # Open TTY descriptor and printer file. We deal only with character + # data, so open printer as a text file. Output the files to the line + # printer device. + + lp = ttyodes (device) + if (ttygets (lp, "DD", Memc[ddstr], SZ_DDSTR) <= 0) + call error (1, "missing 'DD' parameter in termcap entry") + + out = lpopen (Memc[ddstr], APPEND, TEXT_FILE) + + # Output file, followed by a form feed. + iferr { + call xh_print_file (out, lp, fname) + call flush (out) + } then + call erract (EA_WARN) + + call close (out) + call ttycdes (lp) + call sfree (sp) +end + + +# XH_PRINT_FILE -- Open and print the named text file on the output file, +# under control of the tty device descriptor LP. Print a header on each +# page if enabled, and formfeed at the end of the file. The number of lines +# per page is given by the tty descriptor. + +procedure xh_print_file (out, lp, fname) + +int out +pointer lp +char fname[ARB] + +bool one_tab_in +int lineno, maxlines, status, in +pointer sp, ip, lbuf +int open(), getline(), ttystati() +errchk salloc, open, ttystati, getline, ttyputline + +begin + call smark (sp) + call salloc (lbuf, SZ_LINE+1, TY_CHAR) + + in = open (fname, READ_ONLY, TEXT_FILE) + maxlines = ttystati (lp, TTY_NLINES) + + # If printer page is very wide, set page in one tabstop from left + # margin. + + one_tab_in = (ttystati (lp, TTY_NCOLS) > WIDE_PAGE) + if (one_tab_in) { + Memc[lbuf] = '\t' + ip = lbuf + 1 + } else + ip = lbuf + + + # Format and write each page of output. If headers are enabled, + # output formfeed and header between pages. + + status = OK + while (status != EOF) { + # Output one page of text. Each output line is processed by + # ttyputline to expand tabs, underline, etc. + + for (lineno=1; lineno <= maxlines; lineno=lineno+1) { + status = getline (in, Memc[ip]) + if (status == EOF) + break + if (Memc[ip] == '\f') { + call ttyputline (out, lp, "\f", YES) + call strcpy (Memc[ip+1], Memc[ip], SZ_LINE) + } + call ttyputline (out, lp, Memc[lbuf], YES) + } + } + + call close (in) + call sfree (sp) +end diff --git a/pkg/system/help/xhelp/xhqref.x b/pkg/system/help/xhelp/xhqref.x new file mode 100644 index 00000000..51912169 --- /dev/null +++ b/pkg/system/help/xhelp/xhqref.x @@ -0,0 +1,250 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <syserr.h> +include <finfo.h> +include <ctype.h> +include "../help.h" +include "xhelp.h" + +define MAX_PKGS 200 +define SZ_PKG 32 +define EXTPKG "hlib$extern.pkg" + + +# XH_UPDT_QUICKREF -- Update a quick reference file for the help database +# if needed. + +procedure xh_updt_quickref (xh) + +pointer xh + +long fiq[LEN_FINFO], fie[LEN_FINFO] + +int access() +long finfo() +errchk access, finfo + +begin + # If the quickref file exists, and it is older than the + # hlib$extern.pkg file which defines the helpdb rebuild + # the quickref file so we're current, otherwise rebuild + # the quickref file anyway. + if ((access (QUICKREF(xh), 0, 0) == NO) || + (access (PKGFILE, 0, 0) == NO)) { + call xh_make_quickref (xh, QUICKREF(xh)) + } else { + if (finfo (QUICKREF(xh), fiq) == ERR) + call filerr (QUICKREF(xh), SYS_FOPNNEXFIL) + if (finfo (EXTPKG, fie) == ERR) + call filerr (EXTPKG, SYS_FOPNNEXFIL) + + if (FI_MTIME[fie] > FI_MTIME[fiq]) { + call delete (QUICKREF(xh)) + call xh_make_quickref (xh, QUICKREF(xh)) + } + } +end + + +# XH_MAKE_QUICKREF -- Make a quick reference file for the help database. + +procedure xh_make_quickref (xh, quickref) + +pointer xh #i task struct pointer +char quickref[ARB] #i quickref filename + +pointer pkglist, pp +int fdi, fdo, fd_err +int sz_pbuf, npkgs +char fname[SZ_FNAME], efname[SZ_FNAME] +char pkg[SZ_PKG], lastpkg[SZ_PKG], line[SZ_LINE] + +int open(), access(), getline(), gstrcpy(), strsearch(), strcmp() +errchk open + +begin + # Tell the GUI we're actually busy doing something.... + call gmsg (XH_GP(xh), "alert", + "Please wait,\ngenerating QuickRef file...") + call gflush (XH_GP(xh)) + + # Open the STDERR stream onto a dummy file to catch any + # "no help available" messages that may interfere with the + # textout GUI parameter. + call mktemp ("tmp$xerr", efname, SZ_FNAME) + fd_err = open (efname, NEW_FILE, TEXT_FILE) + call frediro (STDERR, fd_err) + + # Open a temp file with the raw search information. + call mktemp ("tmp$xhelpq", fname, SZ_FNAME) + fdi = open (fname, NEW_FILE, TEXT_FILE) + + call xh_get_help (fdi, "[a-z]*.", "", "", HF_HTML, HELPDB(xh), "help", + "references") + call close (fdi) + + # Close the error file, swap back the descriptors first and delete it. + call fswapfd (STDERR, fd_err) + call close (fd_err) + call delete (efname) + + # Delete existing files. + if (access (quickref, 0, 0) == YES) + call delete (quickref) + + # Open the references file. + iferr (fdo = open (quickref, NEW_FILE, TEXT_FILE)) { + call sprintf (line, SZ_LINE, "Cannot create quickref file `%s'.") + call pargstr (quickref) + call error (0, line) + } + fdi = open (fname, READ_ONLY, TEXT_FILE) + + # Initialize for the package list. + pkg[1] = EOS + lastpkg[1] = EOS + npkgs = 0 + sz_pbuf = MAX_PKGS * SZ_PKG + call malloc (pkglist, sz_pbuf, TY_CHAR) + pp = pkglist + + # Loop over the lines in the file, save the ones that are the + # descriptions. Descriptions are assumed to contain a '-' since + # this is standard for .men files, to be safe we also required + # the bracketed package name generated with a 'references' query. + # The package name is used to create the package list symtab we + # use to show the item as a task or package. + + while (getline(fdi,line) != EOF) { + if (strsearch (line, " - ") != 0 && strsearch (line, "[") != 0) { + call putline (fdo, line) + + # Extract the package name. The results aren't sorted at + # this point so we see whether this package is the same as + # the last before adding it to the package list. This + # gives us a unique list of unsorted package names. + + call xh_gname (line, pkg) + if (lastpkg[1] == EOS) + call strcpy (pkg, lastpkg, SZ_PKG) + if (strcmp (pkg, lastpkg) != 0) { + npkgs = npkgs + 1 + + # Protect against overflowing the buffer. + if ((pp - pkglist) > sz_pbuf) + call error (1, "Package buffer overflow.") + + pp = pp + gstrcpy (pkg, Memc[pp], SZ_PKG) + pp = pp + gstrcpy (" ", Memc[pp], SZ_PKG) + call strcpy (pkg, lastpkg, SZ_PKG) + } + } + } + Memc[pp] = EOS + + # Close the new references file. + call close (fdo) + + # Close and delete the references temp files. + call close (fdi) + call delete (fname) + + # Sort the lines of the references file. + call xh_file_sort (quickref) + + # Now send the package list off to be stored for the next time. + call xh_make_pkglist (Memc[pkglist]) + + call mfree (pkglist, TY_CHAR) + + # Tell the GUI we're done. + call gmsg (XH_GP(xh), "alert", "dismiss") + call gflush (XH_GP(xh)) +end + + +# XH_MAKE_PKGLIST -- Update the package symtab file. We are only called +# when updating the quickref database so delete any existing file before +# writing the new one. + +procedure xh_make_pkglist (list) + +char list[ARB] #i package list + +pointer sp, err, pkg +pointer stp, sym +int i, ip, fd + +pointer stopen(), stenter() +int open(), access(), strlen() +errchk open + +begin + call smark (sp) + call salloc (err, SZ_LINE, TY_CHAR) + call salloc (pkg, SZ_FNAME, TY_CHAR) + + # Delete existing files. + if (access(PKGFILE,0,0) == YES) + call delete (PKGFILE) + + # Open the package symtab file. + iferr (fd = open (PKGFILE, NEW_FILE, BINARY_FILE)) { + call sprintf (Memc[err], SZ_LINE, "Can't create pkg symtab `%s'.") + call pargstr (PKGFILE) + call error (0, Memc[err]) + } + + # Sort the list before making the symtab. + call xh_sort_list (list) + + # Open the symtab. + stp = stopen ("package list", LEN_INDEX, LEN_STAB, SZ_SBUF) + + # Enter strings in the symtab. + i = 0 + for (ip=1; list[ip] != EOS; ip=ip+1) { + if (list[ip] == ' ') { + Memc[pkg+i] = EOS + sym = stenter (stp, Memc[pkg], strlen (Memc[pkg]) + 1) + i = 0 + ip = ip + 1 + } + Memc[pkg+i] = list[ip] + i = i + 1 + } + + # Save the symtab file. + call stsqueeze (stp) + call stsave (stp, fd) + + # Clean up. + call stclose (stp) + call close (fd) + call sfree (sp) +end + + +# XH_GNAME -- Extract the package name from a 'references' line. + +procedure xh_gname (line, pkg) + +char line[ARB] #i references line +char pkg[ARB] #o package name in line + +int ip, strlen() + +begin + # Clear trailing whitespace back to the ']' at end of the + # package name. + for (ip=strlen(line); line[ip] != ']' || IS_WHITE(line[ip]); ) + ip = ip - 1 + line[ip] = EOS + + # Move back to starting '[' of package name. + while (line[ip] != '[' && ip > 0) + ip = ip - 1 + + # What's left is the package name, copy it to the output. + call strcpy (line[ip+1], pkg, SZ_PKG) +end diff --git a/pkg/system/help/xhelp/xhroot.x b/pkg/system/help/xhelp/xhroot.x new file mode 100644 index 00000000..9559662a --- /dev/null +++ b/pkg/system/help/xhelp/xhroot.x @@ -0,0 +1,73 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "xhelp.h" + + +# XH_ROOT_PKG -- Make the root package. Search the help database and +# create a package list for all modules found. We add special entries for +# system modules (imfort/math/os) which are not normally in the help tree +# but provide documents. + +procedure xh_root_pkg (xh) + +pointer xh #i struct pointer. + +pointer sp, fname, buf, ip, op, lp +int list + +int xh_pkglist() +int gstrcpy(), fntopnb(), fntgfnb() +bool strne() + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (buf, SZ_FNAME, TY_CHAR) + + # Set initial packages and help databases. This consists of the + # system documentation (in sys$sys.hd), the contents of the + # clpackage module and each of the external packages. + + lp = XH_LPTR(xh) + + # Create an entry for seldom-read system docs. + if (XH_SHOWTYPE(xh) == YES) { + lp = lp + gstrcpy ("imfort. ", Memc[lp], ARB) + lp = lp + gstrcpy ("math. ", Memc[lp], ARB) + lp = lp + gstrcpy ("os. ", Memc[lp], ARB) + } else { + lp = lp + gstrcpy ("imfort ", Memc[lp], ARB) + lp = lp + gstrcpy ("math ", Memc[lp], ARB) + lp = lp + gstrcpy ("os ", Memc[lp], ARB) + } + + # Add the external packages to the list. + list = fntopnb (HELPDB(xh), YES) + while (fntgfnb (list, Memc[fname], SZ_FNAME) != EOF) { + op = buf + ip = fname + while (Memc[ip] != '$' && Memc[ip] != EOS && Memc[ip] != ',') { + Memc[op] = Memc[ip] + ip = ip + 1 + op = op + 1 + } + Memc[op] = EOS + if (strne(Memc[buf],"lib")) { + lp = lp + gstrcpy (Memc[buf], Memc[lp], ARB) + if (XH_SHOWTYPE(xh) == YES) + lp = lp + gstrcpy (".", Memc[lp], ARB) + lp = lp + gstrcpy (" ", Memc[lp], ARB) + } + } + + # Add the clpackage contents to the list. + lp = lp + xh_pkglist (xh, "clpackage", HELPDB(xh), Memc[lp]) + + if (lp > (XH_LPTR(xh) + SZ_HELPLIST)) + call error (1, "Memory error: LIST pointer overflow.") + + # Sort the list so it's presentable. + call xh_sort_list (LIST(xh)) + + call sfree (sp) +end diff --git a/pkg/system/help/xhelp/xhsave.x b/pkg/system/help/xhelp/xhsave.x new file mode 100644 index 00000000..f280146d --- /dev/null +++ b/pkg/system/help/xhelp/xhsave.x @@ -0,0 +1,184 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctype.h> +include "../help.h" +include "xhelp.h" + +define SZ_EXTN 10 + + +# XH_SAVE_FILE -- Save the currently displayed page to the named file in +# the specified format. + +procedure xh_save_file (xh, iname, oname, format, overwrite) + +pointer xh #i package descriptor +char iname[ARB] #i input file +char oname[ARB] #i output filename +char format[ARB] #i format +int overwrite #i overwrite flag + +pointer sp, buf +char extn[SZ_EXTN] + +int access(), fnextn(), strlen(), strcmp() + +begin + if (access (oname, 0, 0) == YES && overwrite == NO) { + call smark (sp) + call salloc (buf, SZ_LINE, TY_CHAR) + call sprintf (Memc[buf], SZ_LINE, + "Operation would overwrite\nexisting file '%s'") + call pargstr (oname) + call gmsg (XH_GP(xh), "alert", Memc[buf]) + call sfree (sp) + return + + } else if (access (oname, 0, 0) == YES) + call delete (oname) + + call aclrc (extn, SZ_EXTN) + + # Strip off any braces around the arguments that were put + # in by the Tcl script. + if (iname[1] == '{') { + call amovc (iname[2], iname, strlen(iname)-2) + iname[strlen(iname)-1] = EOS + } + if (oname[1] == '{') { + call amovc (oname[2], oname, strlen(oname)-2) + oname[strlen(oname)-1] = EOS + } + + switch (format[1]) { + case 's': # source + call fcopy (iname, oname) + case 't': # text + if (fnextn(iname, extn, 3) > 0 && strcmp("hlp", extn) == 0) + call xh_save_text (xh, iname, oname) + else + call fcopy (iname, oname) + case 'h': # html + if (fnextn(iname, extn, 3) > 0 && strcmp("hlp", extn) == 0) + call xh_save_html (xh, iname, oname, YES) + else + call xh_save_html (xh, iname, oname, NO) + case 'p': # postscript + if (fnextn(iname, extn, 3) > 0 && strcmp("hlp", extn) == 0) + call xh_save_ps (xh, iname, oname, YES) + else + call xh_save_ps (xh, iname, oname, NO) + default: + call gmsg (XH_GP(xh), "alert", "Invalid format specifier") + } +end + + +# XH_SAVE_TEXT -- Save the page as a formatted text file. + +procedure xh_save_text (xh, in, out) + +pointer xh #i package descriptor +char in[ARB], out[ARB] #i file names + +char err[SZ_LINE] +int fdout, open() +errchk open + +begin + # Open the output file. + iferr (fdout = open (out, NEW_FILE, TEXT_FILE)) { + call sprintf (err, SZ_LINE, "Cannot open output file `%s'.") + call pargstr (out) + call gmsg (XH_GP(xh), "alert", err) + return + } + + # Format the help as text. + call xh_get_help (fdout, "", "", in, HF_TEXT, HELPDB(xh), "all", "help") + + # Close the file. + call close (fdout) +end + + +# XH_SAVE_HTML -- Save the page as an HTML file. + +procedure xh_save_html (xh, in, out, ishelp) + +pointer xh #i package descriptor +char in[ARB], out[ARB] #i file names +int ishelp #i is this a help file? + +char err[SZ_LINE] +int fdout, fdin, open() +errchk open + +begin + # Open the output file. + iferr (fdout = open (out, NEW_FILE, TEXT_FILE)) { + call sprintf (err, SZ_LINE, "Cannot open output file `%s'.") + call pargstr (out) + call gmsg (XH_GP(xh), "alert", err) + return + } + + # Format the help as text. + if (ishelp == YES) { + call xh_get_help (fdout, "", "", in, HF_HTML, HELPDB(xh), + "all", "help") + } else { + # Open the input file. + iferr (fdout = open (out, NEW_FILE, TEXT_FILE)) { + call sprintf (err, SZ_LINE, "Cannot open output file `%s'.") + call pargstr (out) + call gmsg (XH_GP(xh), "alert", err) + return + } + + call fprintf (out, "<HTML><BODY>\n") + call fprintf (out, "<TITLE>%s</TITLE>\n") + call pargstr (in) + call fprintf (out, "<PRE>\n") + call fcopyo (in, out) + call fprintf (out, "</PRE>\n") + call fprintf (out, "</BODY></HTML>\n") + + call close (fdin) + } + + # Close the file. + call close (fdout) +end + + +# XH_SAVE_PS -- Save the page as a postscript file. + +procedure xh_save_ps (xh, in, out, ishelp) + +pointer xh #i package descriptor +char in[ARB], out[ARB] #i file names +int ishelp #i is this a help file? + +char err[SZ_LINE] +int fdout, open() +errchk open + +begin + if (ishelp == NO) + return + + # Open the output file. + iferr (fdout = open (out, NEW_FILE, TEXT_FILE)) { + call sprintf (err, SZ_LINE, "Cannot open output file `%s'.") + call pargstr (out) + call gmsg (XH_GP(xh), "alert", err) + return + } + + # Format the help as text. + call xh_get_help (fdout, "", "", in, HF_PS, HELPDB(xh), "all", "help") + + # Close the file. + call close (fdout) +end diff --git a/pkg/system/help/xhelp/xhsearch.x b/pkg/system/help/xhelp/xhsearch.x new file mode 100644 index 00000000..18f1aa28 --- /dev/null +++ b/pkg/system/help/xhelp/xhsearch.x @@ -0,0 +1,185 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <fset.h> +include <ctype.h> +include "xhelp.h" + + +# XH_SEARCH -- Given a search pattern generate a list of tasks matching the +# pattern. + +procedure xh_search (xh, exact_match, pattern) + +pointer xh #i task struct pointer +int exact_match #i require an exact match? +char pattern[ARB] #i search pattern + +pointer sp, lfile, line, helpstr, item +pointer tp, lp, pat +char task[SZ_FNAME], pkg[SZ_FNAME], desc[SZ_FNAME] +int i, ip, fd, fdl +long fsize + +long fstatl() +int open(), xh_match(), getline(), gstrcpy() +errchk open, xh_updt_quickref + +begin + call smark (sp) + call salloc (lfile, SZ_FNAME, TY_CHAR) + call salloc (line, SZ_LINE, TY_CHAR) + call salloc (item, SZ_LINE, TY_CHAR) + call salloc (pat, SZ_FNAME, TY_CHAR) + + # Open the quick reference file. + iferr (fd = open (QUICKREF(xh), READ_ONLY, TEXT_FILE)) + call error (0, "Cannot open quick-reference file.") + + # Open the temp file for the matched lines. + call mktemp ("tmp$xhelpq", Memc[lfile], SZ_FNAME) + fdl = open (Memc[lfile], NEW_FILE, TEXT_FILE) + + # Allocate space for the results string. + fsize = fstatl (fd, F_FILESIZE) + + # Check pattern for multi-word searches. + call aclrc (Memc[pat], SZ_FNAME) + for (ip=1; IS_WHITE(pattern[ip]); ip=ip+1) + ; + if (pattern[ip] == '{') { + ip = ip + 1 + for (i=0; pattern[ip] != '}'; ip=ip+1) { + Memc[pat+i] = pattern[ip] + i = i + 1 + } + } else + call strcpy (pattern[ip], Memc[pat], SZ_FNAME) + + # Loop over the lines in the file and match the pattern. + while (getline(fd,Memc[line]) != EOF) { + if (xh_match (Memc[line], Memc[pat], exact_match) != 0) + call putline (fdl, Memc[line]) # save it to the file + } + call close (fdl) + call close (fd) + + # Now read back the file to see if we matched anything, and so we + # can parse the file for task/package names. + fdl = open (Memc[lfile], READ_ONLY, TEXT_FILE) + fsize = fstatl (fdl, F_FILESIZE) + + # See whether we got anything, if not return. + if (fsize == 0) { + call sprintf (Memc[line], SZ_LINE, + "No help available for\npattern `%s'.") + call pargstr (Memc[pat]) + call gmsg (XH_GP(xh), "alert", Memc[line]) + + call close (fdl) + call delete (Memc[lfile]) + call sfree (sp) + return + } + call calloc (helpstr, 5*fsize, TY_CHAR) + + # Read back the sorted list, separate the task name, package, and + # descriptions and format it for the GUI. + tp = helpstr + tp = tp + gstrcpy ("<HTML><BODY><PRE>", Memc[tp], ARB) + while (getline(fdl, Memc[line]) != EOF) { + Memc[item] = EOS + lp = line + + # Get the task name. + for (i=1; !IS_WHITE(Memc[lp]); i=i+1) { + task[i] = Memc[lp] + lp = lp + 1 + if (Memc[lp] == EOS || i >= SZ_FNAME) + break + } + task[i] = EOS + + # Skip delimiter. + while (IS_WHITE(Memc[lp]) || Memc[lp] == '-') + lp = lp + 1 + + # Get the description up to the '[' package name. + for (i=1; Memc[lp] != '['; i=i+1) { + desc[i] = Memc[lp] + lp = lp + 1 + if (Memc[lp] == EOS || i >= SZ_FNAME) + break + } + desc[i] = EOS + + # Get the package name up to the ']' delimiter. + if (Memc[lp] != EOS) { + lp = lp + 1 + for (i=1; Memc[lp] != ']'; i=i+1) { + pkg[i] = Memc[lp] + lp = lp + 1 + if (Memc[lp] == '\n' || Memc[lp] == EOS || i >= SZ_FNAME) + break + } + } + pkg[i] = EOS + + call sprintf(Memc[item], SZ_LINE, "<A HREF=%s.%s>%10.10s</A> ") + call pargstr (pkg) + call pargstr (task) + call pargstr (task) + tp = tp + gstrcpy (Memc[item], Memc[tp], ARB) + call sprintf(Memc[item], SZ_LINE, "<A HREF=%s.%s>%10.10s</A> ") + call pargstr (pkg) + call pargstr (pkg) + call pargstr (pkg) + tp = tp + gstrcpy (Memc[item], Memc[tp], ARB) + call sprintf(Memc[item], SZ_LINE, " %s\n") + call pargstr (desc) + tp = tp + gstrcpy (Memc[item], Memc[tp], ARB) + } + call strcat ("</PRE></BODY></HTML>\n", Memc[tp], SZ_LINE) + Memc[tp] = EOS + call close (fdl) + + # Send it to the GUI. + call gmsg (XH_GP(xh), "apropos", Memc[helpstr]) + + # Clean up. + call delete (Memc[lfile]) + call mfree (helpstr, TY_CHAR) + call sfree (sp) +end + + +# XH_MATCH -- Match any or all words in a pattern against the given line. +# We can either look for an exact match or just the occurence of one word +# in the pattern. + +int procedure xh_match (line, pattern, exact_match) + +char line[ARB] #i line to be matched +char pattern[ARB] #i pattern words +int exact_match + +char word[SZ_FNAME] +int i, j +int strsearch() + +begin + if (exact_match == YES) { + return (strsearch(line, pattern)) + } else { + # See if any word in the pattern matches in the line. + for (i=1; pattern[i] != EOS; i=i+1) { + for (j=1; pattern[i] != EOS && pattern[i] != ' '; j=j+1) { + word[j] = pattern[i] + i = i + 1 + } + word[j] = EOS + if (strsearch(line, word) != 0) + return (YES) + } + return (NO) + } +end diff --git a/pkg/system/help/xhelp/xhsort.x b/pkg/system/help/xhelp/xhsort.x new file mode 100644 index 00000000..b5ccc081 --- /dev/null +++ b/pkg/system/help/xhelp/xhsort.x @@ -0,0 +1,223 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include <ctype.h> +include "xhelp.h" + +define MAXPTR 20000 +define SZ_LINBUF 300000 + + +# XH_SORT_LIST -- Take a list of words (as with a package list) and sort them. + +procedure xh_sort_list (list) + +char list[ARB] #u list to be sorted + +pointer sp, index, buf, ip +int i, j, count, len + +int strlen() + +begin + len = strlen (list) + + call smark (sp) + call salloc (index, SZ_HELPLIST, TY_INT) + call salloc (buf, len+2, TY_CHAR) + + # Build up the index array. + count = 1 + Memi[index] = 1 + for (i=2; i<len; i=i+1) { + if (list[i] == ' ') { + list[i] = EOS + Memi[index+count] = i + 1 + count = count + 1 + } + } + + # Sort the list. + call strsrt (Memi[index], list, count) + + # Restore the list. + ip = buf + do i = 1, count { + for (j=0; list[Memi[index+i-1]+j] != EOS; j=j+1) { + Memc[ip] = list[Memi[index+i-1]+j] + ip = ip + 1 + } + Memc[ip] = ' ' + ip = ip + 1 + } + Memc[ip-1] = EOS + call strcpy (Memc[buf], list, strlen(Memc[buf])) + call sfree (sp) +end + + +# XH_FILE_SORT -- Sort the lines in the named file. + +procedure xh_file_sort (fname) + +char fname[SZ_FNAME] #i file to be sorted + +pointer linbuf, linptr +int nlines, fd +int open() + +begin + call calloc (linptr, MAXPTR, TY_INT) + call calloc (linbuf, SZ_LINBUF, TY_CHAR) + + # Sort the file then write it back out. + fd = open (fname, READ_ONLY, TEXT_FILE) + call xh_gtext (fd, Memi[linptr], nlines, Memc[linbuf]) + call close (fd) + call delete (fname) + + call xh_quick (Memi[linptr], Memc[linbuf], nlines) + + fd = open (fname, NEW_FILE, TEXT_FILE) + call xh_ptext (fd, Memi[linptr], nlines, Memc[linbuf]) + + call mfree (linbuf, TY_CHAR) + call mfree (linptr, TY_INT) + call close (fd) +end + + +# XH_GTEXT -- Get text lines into linbuf. + +procedure xh_gtext (infile, linptr, nlines, linbuf) + +int infile, linptr[ARB], nlines +char linbuf[ARB] + +int lbp, len, getline() +errchk getline + +begin + nlines = 0 + lbp = 1 + + repeat { + len = getline (infile, linbuf[lbp]) + if (len == EOF) + break + else if (len == 1) + # ignore blank lines + else { + nlines = nlines + 1 + linptr[nlines] = lbp + lbp = lbp + len + 1 # '1' = room for EOS + } + } until (lbp >= SZ_LINBUF - SZ_LINE || nlines >= MAXPTR) +end + + +# XH_PTEXT -- Output text lines from linbuf to outfile. + +procedure xh_ptext (outfil, linptr, nlines, linbuf) + +int outfil, linptr[ARB], nlines +char linbuf[ARB] +int i, j +errchk putline + +begin + for (i=1; i <= nlines; i=i+1) { + j = linptr[i] + call putline (outfil, linbuf[j]) + } +end + + +# XH_QUICK -- Quicksort for text data. NOTE -- This algorithm is quadratic in +# the worst case, i.e., when the data is already sorted. A random method of +# selecting the pivot should be used to improve the behaviour on sorted arrays. + +procedure xh_quick (linptr, linbuf, nlines) + +int linptr[ARB] # indices of strings in buffer +char linbuf[ARB] # string buffer +int nlines # number of strings + +define LOGPTR 32 +define swap {temp=$1;$1=$2;$2=temp} + +int i, j, k, temp, lv[LOGPTR], p, pivlin, uv[LOGPTR] +int xh_compare() + +begin + lv[1] = 1 + uv[1] = nlines + p = 1 + + while (p > 0) { + if (lv[p] >= uv[p]) # only one elem in this subset + p = p - 1 # pop stack + else { + # Dummy loop to trigger optimizer. + do p = p, ARB { + i = lv[p] - 1 + j = uv[p] + + # Select pivot element at midpoint of interval to avoid + # quadratic behavior on a sorted list. + + k = (lv[p] + uv[p]) / 2 + swap (linptr[j], linptr[k]) + pivlin = linptr[j] + + while (i < j) { + for (i=i+1; xh_compare (linptr[i], pivlin, linbuf) < 0; + i=i+1) + ; + for (j=j-1; j > i; j=j-1) + if (xh_compare (linptr[j], pivlin, linbuf) <= 0) + break + if (i < j) # out of order pair + swap (linptr[i], linptr[j]) + } + + j = uv[p] # move pivot to position i + swap (linptr[i], linptr[j]) + + if (i-lv[p] < uv[p] - i) { # stack so shorter done first + lv[p+1] = lv[p] + uv[p+1] = i - 1 + lv[p] = i + 1 + } else { + lv[p+1] = i + 1 + uv[p+1] = uv[p] + uv[p] = i - 1 + } + + break + } + + p = p + 1 # push onto stack + } + } +end + + +# XH_COMPARE -- Compare two strings. Return -1 if str1<str2, 1 if str1>str2, +# or 0 if the two strings are equal. + +int procedure xh_compare (lp1, lp2, linbuf) + +int lp1, lp2 # pointers to substrings in linbuf +char linbuf[ARB] # text buffer + +int ip1, ip2, answer +int strcmp() + +begin + for (ip1=lp1; IS_WHITE(linbuf[ip1]); ip1=ip1+1) + ; + for (ip2=lp2; IS_WHITE(linbuf[ip2]); ip2=ip2+1) + ; + answer = strcmp (linbuf[ip1], linbuf[ip2]) + return (answer) +end diff --git a/pkg/system/help/xhelp/zzdebug.x b/pkg/system/help/xhelp/zzdebug.x new file mode 100644 index 00000000..70a95d9b --- /dev/null +++ b/pkg/system/help/xhelp/zzdebug.x @@ -0,0 +1,59 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + + +# ZZDEBUG.X -- Debug routines for the help formatting system. + +task lroff2html = t_lroff2html, + lroff2ps = t_lroff2ps + + +# LROFF2HTML -- Test program to convert an Lroff source file to HTML. + +procedure t_lroff2html () + +int fdi, fdo +char iname[SZ_FNAME], oname[SZ_FNAME] + +int open() +errchk open + +begin + call clgstr ("input", iname, SZ_FNAME) # get parameters + call clgstr ("output", oname, SZ_FNAME) + + fdi = open (iname, READ_ONLY, TEXT_FILE) # open the file + fdo = open (oname, NEW_FILE, TEXT_FILE) + + # Process it. + call lroff2html (fdi, fdo, iname, "", "", "", "") + + call close (fdi) + call close (fdo) +end + + +# LROFF2PS -- Test program to convert an Lroff source file to Postscript. + +procedure t_lroff2ps () + +int fdi, fdo +char iname[SZ_FNAME], oname[SZ_FNAME] + +pointer ps +int open() +errchk open + +begin + call clgstr ("input", iname, SZ_FNAME) # get parameters + call clgstr ("output", oname, SZ_FNAME) + + fdi = open (iname, READ_ONLY, TEXT_FILE) # open the files + fdo = open (oname, READ_ONLY, TEXT_FILE) + + # Process it. + ps = NULL + call lroff2ps (fdi, fdo, ps, "", "") + + call close (fdi) + call close (fdo) +end |