Browse Source

Further simplification

Markelle Kelly 6 years ago
parent
commit
1108cb374d
1 changed files with 103 additions and 194 deletions
  1. 103 194
      packages/toc/src/generators/notebookgenerator/index.ts

+ 103 - 194
packages/toc/src/generators/notebookgenerator/index.ts

@@ -58,7 +58,7 @@ export function createNotebookGenerator(
     generate: panel => {
       let headings: INotebookHeading[] = [];
       let numberingDict: { [level: number]: number } = {};
-      let currentCollapseLevel = -1;
+      let collapseLevel = -1;
       // Keep track of the previous heading, so it can be
       // marked as having a child if one is discovered
       let prevHeading: INotebookHeading | null = null;
@@ -98,7 +98,7 @@ export function createNotebookGenerator(
               headings,
               renderedHeading,
               prevHeading,
-              currentCollapseLevel,
+              collapseLevel,
               options.filtered
             );
           }
@@ -110,7 +110,7 @@ export function createNotebookGenerator(
             if (!htmlData.length) {
               continue;
             }
-            // Generate the heading
+            // If MD/HTML generate the heading and add to headings if applicable
             const outputWidget = (cell as CodeCell).outputArea.widgets[j];
             const onClickFactory = (el: Element) => {
               return () => {
@@ -130,35 +130,21 @@ export function createNotebookGenerator(
               numbering,
               cell
             );
-            // If the heading is MD and it's appropriate, add to headings
-            if (
-              renderedHeading &&
-              renderedHeading.type === 'markdown' &&
-              options.showMarkdown
-            ) {
-              [headings, prevHeading] = Private.addMDOrCode(
-                headings,
-                renderedHeading,
-                prevHeading,
-                currentCollapseLevel,
-                options.filtered
-              );
-            } else if (renderedHeading && renderedHeading.type === 'header') {
-              [headings, prevHeading, currentCollapseLevel] = Private.addHeader(
-                headings,
-                renderedHeading,
-                prevHeading,
-                currentCollapseLevel,
-                options.filtered,
-                collapsed
-              );
-            }
+            [headings, prevHeading, collapseLevel] = Private.processMD(
+              renderedHeading,
+              options.showMarkdown,
+              headings,
+              prevHeading,
+              collapseLevel,
+              options.filtered,
+              collapsed
+            );
           }
         } else if (model.type === 'markdown') {
-          // If the cell is rendered, generate the ToC items from
-          // the HTML. If it is not rendered, generate them from
-          // the text of the cell.
           let mdCell = cell as MarkdownCell;
+          let renderedHeading: INotebookHeading | undefined = undefined;
+          let lastLevel = Private.getLastLevel(headings);
+          // If the cell is rendered, generate the ToC items from the HTML
           if (mdCell.rendered && !mdCell.inputHidden) {
             const onClickFactory = (el: Element) => {
               return () => {
@@ -172,40 +158,16 @@ export function createNotebookGenerator(
                 }
               };
             };
-            let numbering = options.numbering;
-            let lastLevel = Private.getLastLevel(headings);
-            let renderedHeading: INotebookHeading | undefined;
             renderedHeading = Private.getRenderedHTMLHeading(
               cell.node,
               onClickFactory,
               sanitizer,
               numberingDict,
               lastLevel,
-              numbering,
+              options.numbering,
               cell
             );
-            if (
-              renderedHeading &&
-              renderedHeading.type === 'markdown' &&
-              options.showMarkdown
-            ) {
-              [headings, prevHeading] = Private.addMDOrCode(
-                headings,
-                renderedHeading,
-                prevHeading,
-                currentCollapseLevel,
-                options.filtered
-              );
-            } else if (renderedHeading && renderedHeading.type === 'header') {
-              [headings, prevHeading, currentCollapseLevel] = Private.addHeader(
-                headings,
-                renderedHeading,
-                prevHeading,
-                currentCollapseLevel,
-                options.filtered,
-                collapsed
-              );
-            }
+            // If not rendered, generate ToC items from the text of the cell
           } else {
             const onClickFactory = (line: number) => {
               return () => {
@@ -213,96 +175,24 @@ export function createNotebookGenerator(
                 cell.node.scrollIntoView();
               };
             };
-            let lastLevel = Private.getLastLevel(headings);
-            let renderedHeading: INotebookHeading | null = null;
-            if (cell) {
-              renderedHeading = Private.getMarkdownHeading(
-                model!.value.text,
-                onClickFactory,
-                numberingDict,
-                lastLevel,
-                cell
-              );
-            }
-            if (
-              renderedHeading &&
-              renderedHeading.type === 'markdown' &&
-              options.showMarkdown
-            ) {
-              [headings, prevHeading] = Private.addMDOrCode(
-                headings,
-                renderedHeading,
-                prevHeading,
-                currentCollapseLevel,
-                options.filtered
-              );
-            } else if (renderedHeading && renderedHeading.type === 'header') {
-              // Determine whether the heading has children
-              if (
-                prevHeading &&
-                prevHeading.type === 'header' &&
-                prevHeading.level < renderedHeading.level &&
-                !Private.headingIsFilteredOut(renderedHeading, options.filtered)
-              ) {
-                for (let j = headings.length - 1; j >= 0; j--) {
-                  if (headings[j] === prevHeading) {
-                    headings[j].hasChild = true;
-                  }
-                }
-              }
-              // Do not put the item in TOC if its header is collapsed
-              // or filtered out by tags
-              if (
-                (currentCollapseLevel >= renderedHeading.level ||
-                  currentCollapseLevel < 0) &&
-                !Private.headingIsFilteredOut(renderedHeading, options.filtered)
-              ) {
-                headings.push(renderedHeading);
-                if (collapsed) {
-                  currentCollapseLevel = renderedHeading.level;
-                } else {
-                  currentCollapseLevel = -1;
-                }
-              } else if (
-                Private.headingIsFilteredOut(
-                  renderedHeading,
-                  options.filtered
-                ) &&
-                prevHeading &&
-                renderedHeading.level <= prevHeading.level
-              ) {
-                let k = headings.length - 1;
-                let parentHeading = false;
-                while (k >= 0 && parentHeading === false) {
-                  if (headings[k].level < renderedHeading.level) {
-                    prevHeading = headings[k];
-                    parentHeading = true;
-                  }
-                  k--;
-                }
-                if (!parentHeading) {
-                  prevHeading = null;
-                  currentCollapseLevel = -1;
-                } else {
-                  let parentCollapsed = headings[
-                    k + 1
-                  ].cellRef.model.metadata.get('toc-hr-collapsed') as boolean;
-                  parentCollapsed =
-                    parentCollapsed !== undefined ? parentCollapsed : false;
-                  if (parentCollapsed) {
-                    currentCollapseLevel = headings[k + 1].level;
-                  } else {
-                    currentCollapseLevel = -1;
-                  }
-                }
-              }
-              if (
-                !Private.headingIsFilteredOut(renderedHeading, options.filtered)
-              ) {
-                prevHeading = renderedHeading;
-              }
-            }
+            renderedHeading = Private.getMarkdownHeading(
+              model!.value.text,
+              onClickFactory,
+              numberingDict,
+              lastLevel,
+              cell
+            );
           }
+          // Add to headings if applicable
+          [headings, prevHeading, collapseLevel] = Private.processMD(
+            renderedHeading,
+            options.showMarkdown,
+            headings,
+            prevHeading,
+            collapseLevel,
+            options.filtered,
+            collapsed
+          );
         }
       }
       return headings;
@@ -310,13 +200,9 @@ export function createNotebookGenerator(
   };
 }
 
-/**
- * A private namespace for miscellaneous things.
- */
 namespace Private {
   /**
-   * Given a heading and the tags user selected,
-   * determine whether the heading is filtered out by these tags.
+   * Determine whether a heading is filtered out by selected tags.
    */
   export function headingIsFilteredOut(
     heading: INotebookHeading,
@@ -337,9 +223,7 @@ namespace Private {
             }
           }
         }
-        return true;
       }
-      return true;
     }
     return true;
   }
@@ -357,11 +241,47 @@ namespace Private {
     return 0;
   }
 
+  export function processMD(
+    renderedHeading: INotebookHeading | undefined,
+    showMarkdown: boolean,
+    headings: INotebookHeading[],
+    prevHeading: INotebookHeading | null,
+    collapseLevel: number,
+    filtered: string[],
+    collapsed: boolean
+  ): [INotebookHeading[], INotebookHeading | null, number] {
+    // If the heading is MD and MD is shown, add to headings
+    if (
+      renderedHeading &&
+      renderedHeading.type === 'markdown' &&
+      showMarkdown
+    ) {
+      [headings, prevHeading] = Private.addMDOrCode(
+        headings,
+        renderedHeading,
+        prevHeading,
+        collapseLevel,
+        filtered
+      );
+      // Otherwise, if the heading is a header, add to headings
+    } else if (renderedHeading && renderedHeading.type === 'header') {
+      [headings, prevHeading, collapseLevel] = Private.addHeader(
+        headings,
+        renderedHeading,
+        prevHeading,
+        collapseLevel,
+        filtered,
+        collapsed
+      );
+    }
+    return [headings, prevHeading, collapseLevel];
+  }
+
   export function addMDOrCode(
     headings: INotebookHeading[],
     renderedHeading: INotebookHeading,
     prevHeading: INotebookHeading | null,
-    currentCollapseLevel: number,
+    collapseLevel: number,
     filtered: string[]
   ): [INotebookHeading[], INotebookHeading | null] {
     if (
@@ -377,7 +297,7 @@ namespace Private {
           }
         }
       }
-      if (currentCollapseLevel < 0) {
+      if (collapseLevel < 0) {
         headings.push(renderedHeading);
       }
       prevHeading = renderedHeading;
@@ -389,39 +309,34 @@ namespace Private {
     headings: INotebookHeading[],
     renderedHeading: INotebookHeading,
     prevHeading: INotebookHeading | null,
-    currentCollapseLevel: number,
+    collapseLevel: number,
     filtered: string[],
     collapsed: boolean
   ): [INotebookHeading[], INotebookHeading | null, number] {
-    let filter = Private.headingIsFilteredOut(renderedHeading, filtered);
-    if (
-      prevHeading &&
-      prevHeading.type === 'header' &&
-      prevHeading.level < renderedHeading.level &&
-      !filter
-    ) {
-      for (let j = headings.length - 1; j >= 0; j--) {
-        if (headings[j] === prevHeading) {
-          headings[j].hasChild = true;
+    if (!Private.headingIsFilteredOut(renderedHeading, filtered)) {
+      // if the previous heading is a header of a higher level,
+      // find it and mark it as having a child
+      if (
+        prevHeading &&
+        prevHeading.type === 'header' &&
+        prevHeading.level < renderedHeading.level
+      ) {
+        for (let j = headings.length - 1; j >= 0; j--) {
+          if (headings[j] === prevHeading) {
+            headings[j].hasChild = true;
+          }
         }
       }
-    }
-    if (
-      (currentCollapseLevel >= renderedHeading.level ||
-        currentCollapseLevel < 0) &&
-      !filter
-    ) {
-      headings.push(renderedHeading);
-      if (collapsed) {
-        currentCollapseLevel = renderedHeading.level;
-      } else {
-        currentCollapseLevel = -1;
+      // if the collapse level doesn't include the header, or if there is no
+      // collapsing, add to headings and adjust the collapse level appropriately
+      if (collapseLevel >= renderedHeading.level || collapseLevel < 0) {
+        headings.push(renderedHeading);
+        collapseLevel = collapsed ? renderedHeading.level : -1;
       }
-    } else if (
-      filter &&
-      prevHeading &&
-      renderedHeading.level <= prevHeading.level
-    ) {
+      prevHeading = renderedHeading;
+    } else if (prevHeading && renderedHeading.level <= prevHeading.level) {
+      // If header is filtered out and has a previous heading of smaller level, go
+      // back through headings to determine if it has a parent
       let k = headings.length - 1;
       let parentHeading = false;
       while (k >= 0 && parentHeading === false) {
@@ -431,26 +346,20 @@ namespace Private {
         }
         k--;
       }
+      // If there is no parent, set prevHeading to null and reset collapsing
       if (!parentHeading) {
         prevHeading = null;
-        currentCollapseLevel = -1;
+        collapseLevel = -1;
+        // Otherwise, reset collapsing appropriately
       } else {
-        let parentCollapsed = headings[k + 1].cellRef.model.metadata.get(
+        let parentState = headings[k + 1].cellRef.model.metadata.get(
           'toc-hr-collapsed'
         ) as boolean;
-        parentCollapsed =
-          parentCollapsed !== undefined ? parentCollapsed : false;
-        if (parentCollapsed) {
-          currentCollapseLevel = headings[k + 1].level;
-        } else {
-          currentCollapseLevel = -1;
-        }
+        parentState = parentState !== undefined ? parentState : false;
+        collapseLevel = parentState ? headings[k + 1].level : -1;
       }
     }
-    if (!filter) {
-      prevHeading = renderedHeading;
-    }
-    return [headings, prevHeading, currentCollapseLevel];
+    return [headings, prevHeading, collapseLevel];
   }
 
   /**
@@ -607,7 +516,7 @@ namespace Private {
           );
         }
         let html = sanitizer.sanitize(heading.innerHTML, sanitizerOptions);
-        html = html.replace('¶', ''); // Remove the anchor symbol.
+        html = html.replace('¶', '');
         const onClick = onClickFactory(heading);
         let numbering = generateNumbering(numberingDict, level);
         let numDOM = '';