From a926d6bfafc08c527a2c1a47361cdfd0fb377b5b Mon Sep 17 00:00:00 2001 From: Zachary Norman Date: Wed, 6 Mar 2024 12:49:47 -0700 Subject: [PATCH 1/5] WIP: Update build script --- idl/helpers/vscode_buildworkspace.pro | 31 ++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/idl/helpers/vscode_buildworkspace.pro b/idl/helpers/vscode_buildworkspace.pro index 3e5325345..02ba9d346 100644 --- a/idl/helpers/vscode_buildworkspace.pro +++ b/idl/helpers/vscode_buildworkspace.pro @@ -12,12 +12,14 @@ ; A list of procedures and functions for us to resolve ; processed: in, optional, Hash ; A hash that tracks the routines we have processed to limit recursion +; unresolved: in, optional, Hash +; Track unresolved routines ; skip: in, optional, Hash ; A hash that tracks the routines we should skip (internal or not found) ; to limit recursion. ; ;- -pro vscode_BuildWorkspace_resolve, bdg, routines, processed, skip +pro vscode_BuildWorkspace_resolve, bdg, routines, processed, unresolved, skip compile_opt idl2, hidden ; track routines that we have processed @@ -44,6 +46,7 @@ pro vscode_BuildWorkspace_resolve, bdg, routines, processed, skip if (err ne 0) then begin catch, /cancel ; help, /last_message + unresolved[routine] = !null message, /reset continue endif @@ -95,7 +98,7 @@ pro vscode_BuildWorkspace_resolve, bdg, routines, processed, skip if isa(allRoutines['functions'], 'list') then toProcess.add, allRoutines['functions'], /extract ; recurse - vscode_BuildWorkspace_resolve, bdg, toProcess, processed, skip + vscode_BuildWorkspace_resolve, bdg, toProcess, processed, unresolved, skip endif end @@ -298,8 +301,11 @@ pro vscode_BuildWorkspace, workspace if isa(allRoutines['procedures'], 'list') then toProcess.add, allRoutines['procedures'], /extract if isa(allRoutines['functions'], 'list') then toProcess.add, allRoutines['functions'], /extract + ;+ track unresolved datasets + unresolved = hash(/fold_case) + ; recurse - vscode_BuildWorkspace_resolve, bdg, toProcess, processed + vscode_BuildWorkspace_resolve, bdg, toProcess, processed, unresolved ; add object classes for resolving processed['awesomeenviprogress__define'] = !true @@ -332,4 +338,23 @@ pro vscode_BuildWorkspace, workspace ; clean up obj_destroy, bdg + + ; get unresolved names + unresolvedNames = (unresolved.keys()).sort() + + ; check if we have unresolved + if (n_elements(unresolvedNames) gt 0) then begin + ; alert user + print, 'Detected unresolved routines, see "dist/unresolved.json"' + print, ' to make sure critical dependencies are not missing. It is' + print, ' normal to see "ENVI" routines in this list' + + ;+ file we write unresolved routines to + uresolvedUri = outDir + path_sep() + 'unresolved.json' + + ; write to disk + openw, lun, uresolvedUri, /get_lun + printf, lun, json_serialize(unresolvedNames, /pretty) + free_lun, lun + endif end \ No newline at end of file From dbd2c1f04b9a7019f3038d286b855c519a14bd26 Mon Sep 17 00:00:00 2001 From: Zachary Norman Date: Wed, 6 Mar 2024 13:14:08 -0700 Subject: [PATCH 2/5] Separate tasks from classes --- libs/docs/exporter/src/lib/docs-exporter.ts | 121 ++++++++++++++---- .../src/lib/helpers/get-class-link.ts | 22 +++- 2 files changed, 114 insertions(+), 29 deletions(-) diff --git a/libs/docs/exporter/src/lib/docs-exporter.ts b/libs/docs/exporter/src/lib/docs-exporter.ts index 46fd3c901..964747219 100644 --- a/libs/docs/exporter/src/lib/docs-exporter.ts +++ b/libs/docs/exporter/src/lib/docs-exporter.ts @@ -101,11 +101,20 @@ export async function IDLDocsExporter( /** */ const classIndex: string[] = [`# All Classes and Structures`, '']; + /** ENVITask index */ + const enviTaskIndex: string[] = [`# All ENVI Tasks`, '']; + + /** Create envi task sidebar */ + let enviTaskSideBar: any[] = []; + + /** IDLTask index */ + const idlTaskIndex: string[] = [`# All IDL Tasks`, '']; + + /** Create envi task sidebar */ + let idlTaskSideBar: any[] = []; + /** Write all summaries to disk */ for (let i = 0; i < classNames.length; i++) { - const relative = GetClassLink(classNames[i]); - const uri = GetDocsFilepath(exportDir, relative); - /** * Get the display name */ @@ -113,9 +122,42 @@ export async function IDLDocsExporter( ? CleanDocs(GetTaskDisplayName(classes[classNames[i]].display).display) : classes[classNames[i]].display; - // update main list - classIndex.push(`[${useDisplay}](${relative})`); - classIndex.push(''); + /** Default sidebar we append to */ + let updateSidebar = classSideBar; + + /** Default index we update */ + let updateIndex = classIndex; + + // determine where to add our class information + switch (true) { + /** + * ENVI Task + */ + case useDisplay.toLowerCase().startsWith('envitask'): + updateIndex = enviTaskIndex; + updateSidebar = enviTaskSideBar; + break; + + /** + * IDL Task + */ + case useDisplay.toLowerCase().startsWith('idltask'): + updateIndex = idlTaskIndex; + updateSidebar = idlTaskSideBar; + break; + default: + break; + } + + /** Get relative path */ + const relative = GetClassLink(classNames[i]); + + /** Fully qualified filepath */ + const uri = GetDocsFilepath(exportDir, relative); + + // update the index + updateIndex.push(`[${useDisplay}](${relative})`); + updateIndex.push(''); // write to disk WriteFile( @@ -130,14 +172,14 @@ export async function IDLDocsExporter( // create sidebar if (classes[classNames[i]].sidebar.length > 0) { - classSideBar.push({ + updateSidebar.push({ text: classes[classNames[i]].display, link: relative, items: classes[classNames[i]].sidebar, collapsed: true, }); } else { - classSideBar.push({ + updateSidebar.push({ text: classes[classNames[i]].display, link: relative, }); @@ -148,6 +190,12 @@ export async function IDLDocsExporter( classSideBar = classSideBar.sort((a, b) => a.text > b.text ? 1 : b.text > a.text ? -1 : 0 ); + enviTaskSideBar = enviTaskSideBar.sort((a, b) => + a.text > b.text ? 1 : b.text > a.text ? -1 : 0 + ); + idlTaskSideBar = idlTaskSideBar.sort((a, b) => + a.text > b.text ? 1 : b.text > a.text ? -1 : 0 + ); // add classes if we have them if (classSideBar.length > 0) { @@ -160,29 +208,46 @@ export async function IDLDocsExporter( // write content WriteFile(outUri, classIndex.join('\n')); - // update sidebar - // apiSidebar.push({ - // text: 'Classes and Structures', - // items: classSideBar, - // link: relative, - // collapsed: true, - // }); - + // update overall sidebar apiSidebar.push({ text: 'Classes and Structures', - // items: [ - // // { - // // text: `List`, - // // link: relative, - // // }, - // { - // text: 'By Name', - // items: classSideBar, - // collapsed: true, - // }, - // ], link: relative, - // collapsed: true, + }); + } + + // add classes if we have them + if (enviTaskSideBar.length > 0) { + /** Make relative link */ + const relative = `${DOCS_BASE}/${DOCS_PATHS.ENVI_TASK}/index.md`; + + /** Specify the folder */ + const outUri = GetDocsFilepath(exportDir, relative); + + // write content + WriteFile(outUri, enviTaskIndex.join('\n')); + + // update overall sidebar + apiSidebar.push({ + text: 'ENVI Tasks', + link: relative, + }); + } + + // add idl tasks if we have them + if (idlTaskSideBar.length > 0) { + /** Make relative link */ + const relative = `${DOCS_BASE}/${DOCS_PATHS.IDL_TASK}/index.md`; + + /** Specify the folder */ + const outUri = GetDocsFilepath(exportDir, relative); + + // write content + WriteFile(outUri, idlTaskIndex.join('\n')); + + // update overall sidebar + apiSidebar.push({ + text: 'IDL Tasks', + link: relative, }); } diff --git a/libs/docs/exporter/src/lib/helpers/get-class-link.ts b/libs/docs/exporter/src/lib/helpers/get-class-link.ts index 1a3809d6a..6d8690873 100644 --- a/libs/docs/exporter/src/lib/helpers/get-class-link.ts +++ b/libs/docs/exporter/src/lib/helpers/get-class-link.ts @@ -1,3 +1,5 @@ +import { TASK_REGEX } from '@idl/types/core'; + import { DOCS_BASE } from '../docs-exporter.interface'; import { DOCS_PATHS } from '../folder-map.interface'; @@ -5,5 +7,23 @@ import { DOCS_PATHS } from '../folder-map.interface'; * Gets the link for a class */ export function GetClassLink(name: string) { - return `${DOCS_BASE}/${DOCS_PATHS.CLASS}/${name}.md`; + const taskMatch = TASK_REGEX.exec(name); + + /** + * Do we have a task? + */ + if (taskMatch !== null) { + /** Get the name of the task */ + const taskName = taskMatch[1].toLowerCase(); + /** + * Is it an ENVI task? + */ + if (name.toLowerCase().startsWith('envi')) { + return `${DOCS_BASE}/${DOCS_PATHS.ENVI_TASK}/${taskName}.md`; + } else { + return `${DOCS_BASE}/${DOCS_PATHS.IDL_TASK}/${taskName}.md`; + } + } else { + return `${DOCS_BASE}/${DOCS_PATHS.CLASS}/${name}.md`; + } } From 67b4a91365e6cd7cec8e9e24dc2efb3ace111311 Mon Sep 17 00:00:00 2001 From: Zachary Norman Date: Wed, 6 Mar 2024 15:32:41 -0700 Subject: [PATCH 3/5] Document some of the docs patterns --- extension/dev-docs/DOCUMENTATION_PATTERNS.md | 35 ++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 extension/dev-docs/DOCUMENTATION_PATTERNS.md diff --git a/extension/dev-docs/DOCUMENTATION_PATTERNS.md b/extension/dev-docs/DOCUMENTATION_PATTERNS.md new file mode 100644 index 000000000..748971a2a --- /dev/null +++ b/extension/dev-docs/DOCUMENTATION_PATTERNS.md @@ -0,0 +1,35 @@ +# Documentation Patterns + +Captures key logic for exporting documentation for a VSCode workspace as Markdown. + +## General Structure + +"root" is the folder that all docs go to, this is `extension/docs` for the extension + +- `api` is the holder of all of our docs + + - `class` contains class definitions (i.e. summaries) for structures and classes + + - `class/func` contains class function methods by name `class__method` + + - `class/pro` contains class procedure methods by name `class__method` + + - `func` contains all functions by lower-case name + + - `pro` contains all procedures, by lower-case name + + - `task` contains all tasks + + - `task/envi` contains ENVI Tasks by lower-case task name + + - `task/idl` contains IDL Tasks by lower-case task name + +## Linking to Other Routines + +With the pattern outlined above, its very easy to craft links between your docs to different routines. + +For example: + +- To link to a function called, `plot` you make a Markdown link with the value `/api/func/plot.html` + +- To ling to the class summary for `myclass` you make a Markdown link with the value `/api/class/myclass.html` From a664d0718b30618dd27ffbe8fe5f5a89854b2861 Mon Sep 17 00:00:00 2001 From: Zachary Norman Date: Thu, 7 Mar 2024 11:06:55 -0700 Subject: [PATCH 4/5] Fix case --- libs/docs/exporter/src/lib/folder-map.interface.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/docs/exporter/src/lib/folder-map.interface.ts b/libs/docs/exporter/src/lib/folder-map.interface.ts index 78175b373..56b7a5f5f 100644 --- a/libs/docs/exporter/src/lib/folder-map.interface.ts +++ b/libs/docs/exporter/src/lib/folder-map.interface.ts @@ -8,7 +8,7 @@ export const DOCS_PATHS = { /** Where ENVI Tasks go */ ENVI_TASK: join('task', 'envi'), /** Where IDL Tasks go */ - IDL_TASK: join('task', 'IDL'), + IDL_TASK: join('task', 'idl'), /** Where classes go */ CLASS: 'class', }; From b2297af052993b6742ab52829b44536d92c51eda Mon Sep 17 00:00:00 2001 From: Zachary Norman Date: Fri, 15 Mar 2024 15:05:02 -0600 Subject: [PATCH 5/5] If we have valid pixels, stretch on only the valid data --- .../notebooks/envi/helpers/awesomegeneratethumbnail.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/idl/vscode/notebooks/envi/helpers/awesomegeneratethumbnail.pro b/idl/vscode/notebooks/envi/helpers/awesomegeneratethumbnail.pro index 43c547ae0..510add1c1 100644 --- a/idl/vscode/notebooks/envi/helpers/awesomegeneratethumbnail.pro +++ b/idl/vscode/notebooks/envi/helpers/awesomegeneratethumbnail.pro @@ -81,6 +81,9 @@ pro AwesomeGenerateThumbnail, $ ; flatten pixel state if (nChannels gt 1) then pixelState = total(pixelState, 3, /integer) + ; get the pixels that we should keep + idxKeep = where(~pixelState, countKeep) + ; Assign bad pixels to alpha band alpha = (pixelState eq 0) * 255b @@ -105,7 +108,7 @@ pro AwesomeGenerateThumbnail, $ histData = bytarr(dimensions[0], dimensions[1], 3, /nozero) for i = 0, 2 do begin band = data[*, *, i] - oHist = obj_new('IDLcfHistogram', data = band) + oHist = obj_new('IDLcfHistogram', data = countKeep gt 0 ? band[idxKeep] : band) minVal = oHist.stretchValue(2.) maxVal = oHist.stretchValue(98.) histData[*, *, i] = bytscl(band, min = minVal, max = maxVal, /nan)