{"id":"VY4TXYGmqth57Een","meta":{"instanceId":"workflow-3273b7a7","versionId":"1.0.0","createdAt":"2025-09-29T07:07:43.597082","updatedAt":"2025-09-29T07:07:43.597107","owner":"n8n-user","license":"MIT","category":"automation","status":"active","priority":"high","environment":"production"},"name":"Docsify example","nodes":[{"id":"f41906c3-ee4c-4333-bfd5-426f82ba4bd9","name":"CONFIG","type":"n8n-nodes-base.set","position":[660,60],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b48986ec-f58d-4a7f-afba-677edcb28d31","name":"project_path","type":"string","value":"./.n8n/test_docs"},{"id":"cf632419-f839-4045-922c-03784bb3ae07","name":"instance_url","type":"string","value":"={{$env[\"N8N_PROTOCOL\"]}}://{{$env[\"N8N_HOST\"]}}"},{"id":"7a7c70a6-1853-4ca7-b5b1-e36bb0e190d0","name":"HTML_headers","type":"string","value":"=    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n    <meta charset=\"UTF-8\" />\n    <link rel=\"stylesheet\" href=\"//cdn.jsdelivr.net/npm/docsify@4/themes/vue.css\" />\n    <script src=\"{{ $env.WEBHOOK_URL }}\"></script>"},{"id":"1e785afe-f05f-4e51-a164-f341da81ccac","name":"HTML_styles_editor","type":"string","value":"=    <style>\n      body {\n        margin: 0;\n        padding: 0;\n        overflow: hidden;\n      }\n      \n      .container {\n        display: flex;\n        flex-direction: column;\n        height: 100vh;\n        margin: 0;\n      }\n\n      .button-container {\n        display: flex;\n        justify-content: center;\n        gap: 10px;\n        padding: 10px;\n        background: #f8f8f8;\n        border-bottom: 1px solid #eee;\n        width: 50%;\n      }\n\n      .button {\n        padding: 8px 16px;\n        border: none;\n        border-radius: 4px;\n        cursor: pointer;\n        font-size: 14px;\n      }\n\n      .save-button {\n        background: #42b983;\n        color: white;\n      }\n\n      .cancel-button {\n        background: #666;\n        color: white;\n      }\n\n      .editor-preview-container {\n        display: flex;\n        flex: 1;\n        overflow: hidden;\n      }\n      \n      #editor {\n        width: 50%;\n        height: 100%;\n        resize: none;\n        padding: 20px;\n        box-sizing: border-box;\n        font-family: monospace;\n        border: none;\n        border-right: 1px solid #eee;\n      }\n      \n      .preview-container {\n        width: 50%;\n        height: 100%;\n        overflow-y: auto;\n      }\n\n      /* Remove width from main */\n      main {\n        width: auto !important;\n      }\n\n      /* Fix code block wrapping */\n      .markdown-section pre > code {\n        white-space: pre-wrap !important;\n      }\n    </style>"},{"id":"37e22865-7b6b-438d-83a0-dc680d4775cc","name":"HTML_docsify_include","type":"string","value":"=    <script src=\"//cdn.jsdelivr.net/npm/docsify@4\"></script>"}]},"includeOtherFields":true},"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"75cdf7fc-3dfa-49c1-bdbf-01d8be08aaa4","name":"Convert to File","type":"n8n-nodes-base.convertToFile","position":[4020,1600],"parameters":{"options":{},"operation":"toText","sourceProperty":"workflowdata"},"typeVersion":1.1,"notes":"This convertToFile node performs automated tasks as part of the workflow."},{"id":"3868011e-8374-496a-b3f5-4cbf7bde4e56","name":"HasFile?","type":"n8n-nodes-base.if","position":[2400,880],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"2d9feb22-49d1-4354-9b0b-b82da2b20678","operator":{"type":"number","operation":"gt"},"leftValue":"={{ Object.keys($json).length }}","rightValue":0}]}},"typeVersion":2.2,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"0bf2317b-2534-4022-9a16-395d4b44680c","name":"Extract from File","type":"n8n-nodes-base.extractFromFile","position":[2660,860],"parameters":{"options":{},"operation":"text","destinationKey":"YOUR_CREDENTIAL_HERE"},"typeVersion":1,"notes":"This extractFromFile node performs automated tasks as part of the workflow."},{"id":"4b44a7f3-09bf-46a8-9520-247993af654b","name":"Main Page","type":"n8n-nodes-base.html","position":[4660,-100],"parameters":{"html":"<!DOCTYPE html>\n<html>\n  <head>\n{{ $('CONFIG').first().json.HTML_headers }}\n  <body>\n    <div data-app id=\"main\">Please wait...</div>\n    <script>\n      \n      mermaid.initialize({\n        startOnLoad: false,\n      });\n      let svgCounter = 0;\n\n      window.$docsify = {\n        el: '#main',\n        auto2top: true,\n        loadSidebar: 'summary.md',\n        basePath: '{{ $json.webhookUrl.split($json.webhookUrl.extractDomain())[1] }}/',\n        name: 'All Workflows',\n        markdown: {\n          renderer: {\n            code(code, lang) {\n              if (lang === \"mermaid\") {\n                const svgName = `mermaid-svg-${svgCounter++}`;\n                const MERMAID_CONTAINER_ID = `${svgName}-container`;\n                mermaid.render(svgName, code).then(({ svg }) => {\n                  const containerElement = document.querySelector(\n                    `#${MERMAID_CONTAINER_ID}`\n                  );\n                  if (containerElement) {\n                    containerElement.innerHTML = svg;\n                  } else {\n                    console.error(`Error: #${MERMAID_CONTAINER_ID} not found`);\n                  }\n                });\n                return `<div class=\"mermaid\" id=\"${MERMAID_CONTAINER_ID}\"></div>`;\n              }\n              return this.origin.code.apply(this, arguments);\n            },\n          },\n        },        \n        plugins: [\n          function(hook, vm) {\n            hook.ready(function() {\n              // Check if URL doesn't end with slash but also isn't a file path\n              if (!window.location.pathname.endsWith('/') && !window.location.pathname.includes('.')) {\n                // Use history.replaceState to avoid adding to browser history\n                const newUrl = window.location.pathname + '/' + window.location.hash;\n                window.history.replaceState(null, null, newUrl);\n              }\n            });\n          }\n        ],        \n      };\n    </script>\n{{ $('CONFIG').first().json.HTML_docsify_include }}\n  </body>\n</html>"},"typeVersion":1.2,"notes":"This html node performs automated tasks as part of the workflow."},{"id":"28c29cec-7efd-4f05-bf53-ac08cc3834a1","name":"Instance overview","type":"n8n-nodes-base.html","position":[4660,160],"parameters":{"html":"# Your n8n instance workflows:\n\n| Workflow | Status | Docs | Created | Updated | Nodes | Triggers |\n|----------|:------:|------|---------|---------|-------|----------|\n{{ $jmespath($input.all(),'[].json.content').join('\\n') }}"},"executeOnce":true,"typeVersion":1.2,"notes":"This html node performs automated tasks as part of the workflow."},{"id":"3e8eb52e-8d35-4aa3-a485-6674d67720dc","name":"Sort-workflows","type":"n8n-nodes-base.sort","position":[2080,160],"parameters":{"options":{},"sortFieldsUi":{"sortField":[{"order":"descending","fieldName":"updatedAt"}]}},"typeVersion":1,"notes":"This sort node performs automated tasks as part of the workflow."},{"id":"2178e1cf-90b8-4779-9b5c-3d6180823c95","name":"doc action","type":"n8n-nodes-base.switch","position":[1740,1080],"parameters":{"rules":{"values":[{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"ee386c7d-1abe-4864-bb3a-a19d3816c906","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.query.action }}","rightValue":"view"}]},"renameOutput":true},{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"aa1a33ee-ac38-4ea4-9a4c-d355e7de1312","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.query.action }}","rightValue":"edit"}]},"renameOutput":true},{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"676c36e1-4c88-4314-9317-abc877ff3d17","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.query.action }}","rightValue":"recreate"}]},"renameOutput":true},{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"164314cf-7d99-4716-9949-b9196ce47959","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.query.action }}","rightValue":"save"}]},"renameOutput":true}]},"options":{"fallbackOutput":"extra"}},"typeVersion":3.2,"notes":"This switch node performs automated tasks as part of the workflow."},{"id":"7f4aab9b-b7e8-4920-98e8-af8f504a1333","name":"Empty Set","type":"n8n-nodes-base.set","position":[2000,960],"parameters":{"options":{}},"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"1f35bc3e-29d7-47a2-a1c7-cf6052d99993","name":"Load Doc File","type":"n8n-nodes-base.readWriteFile","position":[1900,860],"parameters":{"options":{},"fileSelector":"={{ $('CONFIG').first().json.project_path }}/{{ $json.params.file }}"},"typeVersion":1,"alwaysOutputData":true,"notes":"This readWriteFile node performs automated tasks as part of the workflow."},{"id":"c0805f50-8f8c-49ba-b0c7-6768bf89798c","name":"Respond with markdown","type":"n8n-nodes-base.respondToWebhook","position":[4920,1040],"parameters":{"options":{"responseCode":200,"responseHeaders":{"entries":[{"name":"Content-Type","value":"text/markdown"}]}},"respondWith":"text","responseBody":"={{ $json.html }}"},"typeVersion":1.1,"notes":"This respondToWebhook node performs automated tasks as part of the workflow."},{"id":"9c7a18b9-a081-4162-94f4-e125d666cbcc","name":"Respond with HTML","type":"n8n-nodes-base.respondToWebhook","position":[4920,860],"parameters":{"options":{"responseCode":200,"responseHeaders":{"entries":[{"name":"Content-Type","value":"text/html"}]}},"respondWith":"text","responseBody":"={{ $json.html }}"},"typeVersion":1.1,"notes":"This respondToWebhook node performs automated tasks as part of the workflow."},{"id":"50944148-eb7c-4c28-99c5-478ddb2596f2","name":"Save New Doc File","type":"n8n-nodes-base.readWriteFile","position":[4180,1600],"parameters":{"options":{},"fileName":"={{ $('CONFIG').first().json.project_path }}/{{ $('CONFIG').first().json.params.file }}","operation":"write"},"typeVersion":1,"alwaysOutputData":true,"notes":"This readWriteFile node performs automated tasks as part of the workflow."},{"id":"6d7e0dcf-d12b-4428-9c5e-ef7fb2c6be28","name":"Blank Doc File","type":"n8n-nodes-base.set","position":[4000,1080],"parameters":{"options":{},"assignments":{"assignments":[{"id":"b168d9b1-1a13-4915-b59b-8a17258fd9cc","name":"workflowdata","type":"string","value":"=# {{ $json.name }}\n\n## Workflow Description\n!> Please write what is this workflow doing\n\n## Workflow schematic\n\n```mermaid\n{{ $json.mermaidChart }}\n```\n\n## Any further information\n\n> You can also add tables like this:\n\n| Parameter | Value |\n|-----------|-------|\n| Created | {{ $json.createdAt }} |\n| Last updated | {{ $json.updatedAt }} |\n| Author | {{ $json.shared[0].project.name }} |\n\n"}]},"includeOtherFields":true},"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"778a97eb-f7a2-4537-81fc-979dc6c674a2","name":"Fetch Single Workflow1","type":"n8n-nodes-base.n8n","position":[2820,1200],"parameters":{"operation":"get","workflowId":{"__rl":true,"mode":"id","value":"={{ $('CONFIG').first().json.params.file.replaceAll('docs_','').split('.md')[0] }}"},"requestOptions":{}},"credentials":{"n8nApi":{"id":"eW7IdTFt4ARJbEwR","name":"Ted n8n account"}},"typeVersion":1,"notes":"This n8n node performs automated tasks as part of the workflow."},{"id":"092b8c67-77f9-4d4b-aa26-8f0e3ea3ed29","name":"Fill Workflow Table","type":"n8n-nodes-base.set","position":[2280,160],"parameters":{"options":{},"assignments":{"assignments":[{"id":"3bed44f3-7fa6-4d28-8a6e-7074ca354cd6","name":"content","type":"string","value":"=| [{{ `${$json.name.replace(/[|\\\\[\\]`_*{}()<>#+-]/g, '\\\\$&')}` }}]({{ `${$('CONFIG').first().json.instance_url}/workflow/${$json.id}` }} \"Click to open workflow in n8n\") | {{ $json.active ? '[:green_circle:](# \"Active\")' : '[:white_circle:](# \"Inactive\")' }} | <nobr>[:book:]({{ `docs_${$json.id}?action=view` }} \"View docs\") [:memo:]({{ `docs_${$json.id}.md?action=edit` }} \":ignore Edit\") [:arrows_counterclockwise:]({{ `docs_${$json.id}?action=recreate` }} \"Recreate docs\")</nobr> | <nobr>{{ `${new Date($json.createdAt).toISOString().replace('T', ' ').slice(0, 16)}` }}</nobr> | <nobr>{{ `${new Date($json.updatedAt).toISOString().replace('T', ' ').slice(0, 16)}` }}</nobr> | {{ $json.nodes.length }} | {{ $json.nodes.filter(n => n.type.includes('Trigger')).length }} |"}]}},"executeOnce":false,"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"18c58a09-0dfe-4cb4-ae7f-503957eabadb","name":"Basic LLM Chain","type":"n8n-nodes-base.noOp","onError":"continueRegularOutput","position":[3480,1200],"parameters":{"text":"=Here's the workflow data:\n{{Object.assign(\n  Object.fromEntries(Object.entries($json).filter(([key]) => !['staticData', 'pinData'].includes(key))),\n  {nodes: $json.nodes.map(node => Object.fromEntries(Object.entries(node).filter(([key]) => !['id', 'position'].includes(key))))}\n).toJsonString() }}","messages":{"messageValues":[{"message":"=Your task is to generate simple workflow documentation for the n8n workflows. The user will provide a JSON structure. Reply \nin JSON format in 2 sections: workflow_desription and nodes_settings. Important! Each json key should be a simple markdown text without any additional comments or remarks from your end.\n\nInstruction for `workflow_desription`:\n```\n## Section header with H2\n\\n\n> subline with who created workflow and when, when it was last edited and the status (active / inactive as the green / grey round emoji). Also, when the documentation was generated. Now is: {{ $now }}.\n\\n\\n\nShould contain a description of the workflow. in a couple of paragraphs. Use direct voice without the fluff\n```\n\nInstruction for `nodes_settings`:\n```\n## Section header with H2.\n\\n\n### Node 1 name as H3 title\n  - For each node make a bullet list with the main node configs. Ignore irrelevant configs. Enclose each config value in code backticks (`). Look:\n  - Parameter 1 name: `Parameter 1 value`\n  - Parameter 2 name: `Parameter 2 value`\n\\n\\n\n### Node 2 name as H3 title\n  - For each node make a bullet list with the main node configs. Ignore irrelevant configs. Enclose each config value in code backticks (`). Look:\n  - Parameter 1 name: `Parameter 1 value`\n  - Parameter 2 name: `Parameter 2 value`\n\\n\\n\n```"}]},"promptType":"define","hasOutputParser":true},"typeVersion":1,"alwaysOutputData":false,"notes":"This chainLlm node performs automated tasks as part of the workflow."},{"id":"9bc58cd3-a55e-4cda-95b5-7fa8dc0e7076","name":"OpenAI Chat Model","type":"n8n-nodes-base.noOp","position":[3480,1360],"parameters":{"model":"gpt-4-turbo","options":{"timeout":120000,"temperature":0.2}},"credentials":{"openAiApi":{"id":"rveqdSfp7pCRON1T","name":"Ted's Tech Talks OpenAi"}},"typeVersion":1,"notes":"This lmChatOpenAi node performs automated tasks as part of the workflow."},{"id":"38fb6192-b8ce-4241-a9fe-aebda09aa8d5","name":"Structured Output Parser","type":"n8n-nodes-base.noOp","position":[3820,1360],"parameters":{"jsonSchemaExample":"{\n\t\"workflow_description\": \"## Workflow overview\\n\\n>some additiona info\\n\\nWorkflow desctiption\",\n\t\"nodes_settings\": \"## Nodes settings\\n\\n###Node name 1\\n\\n-  Setting 1\\n-  Setting 2###Node name 2\\n\\n-  Setting 1\\n-  Setting 2\"\n}"},"typeVersion":1,"notes":"This outputParserStructured node performs automated tasks as part of the workflow."},{"id":"29261bbb-dbbb-44df-b99d-bb084df7d846","name":"Auto-fixing Output Parser","type":"n8n-nodes-base.noOp","position":[3580,1360],"parameters":{"options":{}},"typeVersion":1,"notes":"This outputParserAutofixing node performs automated tasks as part of the workflow."},{"id":"086a57cf-a2b4-4f32-8ca6-38546e4856c1","name":"Respond with main page HTML","type":"n8n-nodes-base.respondToWebhook","position":[4920,-100],"parameters":{"options":{"responseCode":200,"responseHeaders":{"entries":[{"name":"Content-Type","value":"text/html"}]}},"respondWith":"text","responseBody":"={{ $json.html }}"},"typeVersion":1.1,"notes":"This respondToWebhook node performs automated tasks as part of the workflow."},{"id":"fdbfe60b-e677-4897-ab1a-9a9f506bba27","name":"Workflow Tags","type":"n8n-nodes-base.html","position":[4660,500],"parameters":{"html":"- **Click to filter by tag:**\n{{ [...new Set($jmespath($input.all(),'[].json.tags[].name'))].map(tag => `- [${tag}](tag-${encodeURIComponent(tag)})`).join('\\n') }}"},"executeOnce":true,"typeVersion":1.2,"notes":"This html node performs automated tasks as part of the workflow."},{"id":"94a258ed-c07c-42d4-8d37-3395fad205b0","name":"No Operation, do nothing","type":"n8n-nodes-base.noOp","position":[1740,1880],"parameters":{},"typeVersion":1,"notes":"This noOp node performs automated tasks as part of the workflow."},{"id":"c35ca075-52e7-4c2f-9891-f709afe36e52","name":"Merge","type":"n8n-nodes-base.merge","position":[3140,1100],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition","numberInputs":3},"typeVersion":3,"notes":"This merge node performs automated tasks as part of the workflow."},{"id":"55a1e32f-b20c-4b1f-9d6f-9bc4ec221fab","name":"Fallback file name","type":"n8n-nodes-base.html","position":[4660,1900],"parameters":{"html":"> File: {{ $json.params.file }}"},"typeVersion":1.2,"notes":"This html node performs automated tasks as part of the workflow."},{"id":"3eef159b-99ad-4c9a-82f4-13bf16972521","name":"mkdir","type":"n8n-nodes-base.executeCommand","position":[2100,1060],"parameters":{"command":"=mkdir -p {{$('CONFIG').first().json.project_path}}"},"typeVersion":1,"notes":"This executeCommand node performs automated tasks as part of the workflow."},{"id":"15fda233-925b-4a4d-964e-1916c0cd39a2","name":"Merge1","type":"n8n-nodes-base.merge","position":[2240,880],"parameters":{"mode":"chooseBranch"},"typeVersion":3,"notes":"This merge node performs automated tasks as part of the workflow."},{"id":"3e6c9243-d5f7-4f04-8231-9994963df36d","name":"Edit Page","type":"n8n-nodes-base.html","position":[4660,860],"parameters":{"html":"<!DOCTYPE html>\n<html>\n  <head>\n{{ $('CONFIG').first().json.HTML_headers }}\n{{ $('CONFIG').first().json.HTML_styles_editor }}\n  </head>\n  <body>\n    <div class=\"container\">\n      <div class=\"button-container\">\n        <button class=\"button save-button\" onclick=\"saveContent()\">Save</button>\n        <button class=\"button cancel-button\" onclick=\"closeWindow()\">Cancel</button>\n      </div>\n      <div class=\"editor-preview-container\">\n        <textarea id=\"editor\">{{ $json.workflowdata }}</textarea>\n        <div class=\"preview-container\">\n          <div id=\"preview\"></div>\n        </div>\n      </div>\n    </div>\n    \n<script>\n  const editor = document.getElementById('editor');\n  let vm;\n\n      mermaid.initialize({\n        startOnLoad: false,\n      });\n\n      let svgCounter = 0;\n\n      // Function to save content\n      async function saveContent() {\n        try {\n          const response = await fetch(window.location.pathname + '?action=save', {\n            method: 'POST',\n            headers: {\n              'Content-Type': 'application/json',\n            },\n            body: JSON.stringify({\n              content: editor.value\n            })\n          });\n          \n          if (response.ok) {\n            alert('Successfully saved!');\n          } else {\n            alert('Failed to save content');\n          }\n        } catch (error) {\n          console.error('Error saving content:', error);\n          alert('Error saving content');\n        }\n      }\n  \n      // Function to close window\n      function closeWindow() {\n        window.close();\n      }\n   \n  window.$docsify = {\n    el: '#preview',\n    loadSidebar: false,\n    loadNavbar: false,\n    basePath: '/',\n    hideSidebar: true,\n        markdown: {\n          renderer: {\n            code(code, lang) {\n              if (lang === \"mermaid\") {\n                const svgName = `mermaid-svg-${svgCounter++}`;\n                const MERMAID_CONTAINER_ID = `${svgName}-container`;\n                mermaid.render(svgName, code).then(({ svg }) => {\n                  const containerElement = document.querySelector(\n                    `#${MERMAID_CONTAINER_ID}`\n                  );\n                  if (containerElement) {\n                    containerElement.innerHTML = svg;\n                  } else {\n                    console.error(`Error: #${MERMAID_CONTAINER_ID} not found`);\n                  }\n                });\n                return `<div class=\"mermaid\" id=\"${MERMAID_CONTAINER_ID}\"></div>`;\n              }\n              return this.origin.code.apply(this, arguments);\n            },\n          },\n        },\n    plugins: [\n      function(hook, _vm) {\n        vm = _vm;\n        \n        hook.beforeEach(function(content) {\n          return editor.value;\n        });\n      }\n    ]\n  };\n  \nlet timeout;\nfunction updatePreview() {\n  clearTimeout(timeout);\n  timeout = setTimeout(() => {\n    if (vm) {\n      const markdownSection = document.querySelector('.markdown-section');\n      if (markdownSection) {\n        const compiler = new window.DocsifyCompiler({\n          basePath: '/',\n          relativePath: false,\n          fallbackLanguages: [],\n          nameLink: '/',\n          routerMode: 'hash'\n        }, vm.router);\n        \n        const html = compiler.compile(editor.value);\n        markdownSection.innerHTML = html;\n        window.Prism.highlightAll();\n\n        // Re-render all mermaid diagrams\n        const mermaidDivs = markdownSection.querySelectorAll('pre[data-lang=\"mermaid\"] code');\n        mermaidDivs.forEach((div, index) => {\n          const code = div.textContent;\n          const svgName = `mermaid-svg-${svgCounter++}`;\n          const MERMAID_CONTAINER_ID = `${svgName}-container`;\n          \n          // Replace the <pre> element with our container\n          const container = document.createElement('div');\n          container.className = 'mermaid';\n          container.id = MERMAID_CONTAINER_ID;\n          div.parentElement.replaceWith(container);\n          \n          // Render the diagram\n          mermaid.render(svgName, code).then(({ svg }) => {\n            const containerElement = document.getElementById(MERMAID_CONTAINER_ID);\n            if (containerElement) {\n              containerElement.innerHTML = svg;\n            }\n          });\n        });\n      }\n    }\n  }, 500);\n};\n  \n  editor.addEventListener('input', updatePreview);\n</script>\n{{ $('CONFIG').first().json.HTML_docsify_include }}\n  </body>\n</html>"},"typeVersion":1.2,"notes":"This html node performs automated tasks as part of the workflow."},{"id":"71e136d5-bb5b-4eab-8cab-bfc50ea2a5a5","name":"Workflow md content","type":"n8n-nodes-base.html","position":[4660,1040],"parameters":{"html":"{{ $json.workflowdata }}"},"executeOnce":true,"typeVersion":1.2,"notes":"This html node performs automated tasks as part of the workflow."},{"id":"6cb6f3b8-de65-43a5-9df3-48299ba7fcce","name":"Is Action Edit?1","type":"n8n-nodes-base.if","position":[3300,1100],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"856cdb3b-a187-4db5-b77b-43ee086780ee","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.query.action }}","rightValue":"edit"}]}},"typeVersion":2.2,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"aff9ed71-bb49-4170-9ae3-5f05f89bab05","name":"Is Action Edit?2","type":"n8n-nodes-base.if","position":[4180,880],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e3648023-8cb7-4b82-bd35-1ba196458327","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.query.action }}","rightValue":"edit"}]}},"typeVersion":2.2,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"7b3d31a9-ee01-4bce-bc5b-78161536999d","name":"Generate Mermaid Chart","type":"n8n-nodes-base.code","position":[3000,1260],"parameters":{"jsCode":"const workflow = $input.first().json;\n\n// Extract nodes from the workflow\nconst nodes = workflow.nodes || [];\n\n// Node types to exclude\nconst excludedNodeTypes = ['n8n-nodes-base.stickyNote'];\n\n// Define shapes and their corresponding brackets\n// {{ $env.WEBHOOK_URL }}\nconst shapes = {\n    'rect': ['[', ']'],\n    'rhombus': ['{', '}'],\n    'circle': ['((', '))'],\n    'hexagon': ['{{', '}}'],\n    'subroutine': ['[[', ']]'],\n    'parallelogram': ['[\\/', '\\/]'],\n    'wait': ['(', ')']\n    // Add more shapes here as needed\n};\n\n// Define special shapes for specific node types\nconst specialShapes = {\n    'n8n-nodes-base.if': 'rhombus',\n    'n8n-nodes-base.switch': 'rhombus',\n    'n8n-nodes-base.code': 'subroutine',\n    'n8n-nodes-base.executeWorkflow': 'subroutine',\n    'n8n-nodes-base.httpRequest':'parallelogram',\n    'n8n-nodes-base.wait':'wait'\n    // List more special node types\n};\n\n// Function to get the shape for a node type\nfunction getNodeShape(nodeType) {\n    return specialShapes[nodeType] || 'rect';\n}\n\n// Create a map of node names to their \"EL<N>\" identifiers, disabled status, and shape\nconst nodeMap = {};\nlet nodeCounter = 1;\nnodes.forEach((node) => {\n    if (!excludedNodeTypes.includes(node.type)) {\n        const shape = getNodeShape(node.type);\n        nodeMap[node.name] = {\n            id: `EL${nodeCounter}`,\n            disabled: node.disabled || false,\n            shape: shape,\n            brackets: shapes[shape] || shapes['rect'] // Default to rect if shape not found\n        };\n        nodeCounter++;\n    }\n});\n\n// Function to convert special characters to HTML entities\nfunction convertToHTMLEntities(str) {\n    return str.replaceAll('\"',\"'\").replace(/[^\\w\\s-]/g, function(char) {\n        return '&#' + char.charCodeAt(0) + ';';\n    });\n}\n\n// Function to format node text (with strike-through if disabled)\nfunction formatNodeText(nodeName, isDisabled) {\n    const escapedName = convertToHTMLEntities(nodeName);\n    return isDisabled ? `<s>${escapedName}</s>` : escapedName;\n}\n\n// Generate connections and isolated nodes\nconst connections = [];\nconst isolatedNodes = new Set(Object.keys(nodeMap));\n\nif (workflow.connections) {\n    Object.entries(workflow.connections).forEach(([sourceName, targetConnections]) => {\n        Object.entries(targetConnections).forEach(([connectionType, targets]) => {\n            targets.forEach(targetArray => {\n                targetArray.forEach(target => {\n                    const sourceNode = nodeMap[sourceName];\n                    const targetNode = nodeMap[target.node];\n                    if (sourceNode && targetNode) {\n                        let connectionLine = `    ${sourceNode.id}${sourceNode.brackets[0]}${formatNodeText(sourceName, sourceNode.disabled)}${sourceNode.brackets[1]}`;\n                        if (connectionType === 'main') {\n                            connectionLine += ` -->`;\n                        } else {\n                            connectionLine += ` -.- |${connectionType}|`;\n                        }\n                        connectionLine += ` ${targetNode.id}${targetNode.brackets[0]}${formatNodeText(target.node, targetNode.disabled)}${targetNode.brackets[1]}`;\n                        connections.push(connectionLine);\n                        isolatedNodes.delete(sourceName);\n                        isolatedNodes.delete(target.node);\n                    }\n                });\n            });\n        });\n    });\n}\n\n// Add isolated nodes to the connections array\nisolatedNodes.forEach(nodeName => {\n    const node = nodeMap[nodeName];\n    connections.push(`    ${node.id}${node.brackets[0]}${formatNodeText(nodeName, node.disabled)}${node.brackets[1]}`);\n});\n\n// Generate the Mermaid flowchart string\nconst mermaidChart = `---\nconfig:\n  look: neo\n  theme: default\n---\nflowchart LR\n${connections.join('\\n')}`;\n\n// Output the result\nreturn {\n    json: {\n        mermaidChart: mermaidChart\n    }\n};"},"typeVersion":2,"notes":"This code node performs automated tasks as part of the workflow."},{"id":"77a35cd5-cb8f-4ac5-a699-dff5e65cda09","name":"Merge2","type":"n8n-nodes-base.merge","position":[3840,1140],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3,"notes":"This merge node performs automated tasks as part of the workflow."},{"id":"f8119590-e9d7-4513-9da4-fa911165baff","name":"Generated Doc","type":"n8n-nodes-base.set","position":[4000,1240],"parameters":{"options":{},"assignments":{"assignments":[{"id":"7693348d-5129-4a07-809d-b0619b9fc44b","name":"workflowdata","type":"string","value":"=# {{ $json.name }}\n\n{{ $json?.output?.workflow_description || \"## <SORRY, COULD NOT GENERATE WORKFLOW DESCRIPTION>\" }}\n\n## Workflow schematic\n\n```mermaid\n{{ $json.mermaidChart }}\n```\n\n{{ $json?.output?.nodes_settings || \"## <SORRY, COULD NOT GENERATE DOCS FOR NODE SETTING>\" }}"}]}},"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"92565206-6cf2-4243-9143-4f6def4b524d","name":"Passthrough","type":"n8n-nodes-base.noOp","position":[2100,1240],"parameters":{},"typeVersion":1,"notes":"This noOp node performs automated tasks as part of the workflow."},{"id":"73081fc3-9554-4a12-b985-da02b356616f","name":"Merge3","type":"n8n-nodes-base.merge","position":[3140,880],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3,"notes":"This merge node performs automated tasks as part of the workflow."},{"id":"f50e72f8-9027-4ca7-9df7-700e828f48eb","name":"Merge4","type":"n8n-nodes-base.merge","position":[960,-100],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3,"notes":"This merge node performs automated tasks as part of the workflow."},{"id":"306820ac-7c87-45c2-b76f-55d772ac7300","name":"Merge5","type":"n8n-nodes-base.merge","position":[960,240],"parameters":{"mode":"combine","options":{},"combineBy":"combineByPosition"},"typeVersion":3,"notes":"This merge node performs automated tasks as part of the workflow."},{"id":"96fd7265-7920-453f-8309-bdbd10880d03","name":"Edit Fields","type":"n8n-nodes-base.set","position":[2100,1600],"parameters":{"options":{},"assignments":{"assignments":[{"id":"8bc55c5b-e09a-459b-bbb6-ed5f70d4f353","name":"workflowdata","type":"string","value":"={{ $json.body.content }}"}]},"includeOtherFields":true},"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"2fffb547-1c11-4663-aed5-29b9557e8738","name":"Is Action Save?","type":"n8n-nodes-base.if","position":[4540,1600],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"e3648023-8cb7-4b82-bd35-1ba196458327","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json?.query?.action }}","rightValue":"save"},{"id":"a44c9cc5-5717-4c34-978b-e644219a9cc1","operator":{"type":"string","operation":"exists","singleValue":true},"leftValue":"={{ $json?.query?.action }}","rightValue":""}]}},"typeVersion":2.2,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"15825037-a8e2-4fbc-b529-2bf89810a116","name":"Merge6","type":"n8n-nodes-base.merge","position":[4360,1700],"parameters":{"mode":"chooseBranch","useDataOfInput":2},"typeVersion":3,"notes":"This merge node performs automated tasks as part of the workflow."},{"id":"b47f18a4-9b59-4278-890d-b6f6c596c554","name":"Respond OK on Save","type":"n8n-nodes-base.respondToWebhook","position":[4920,1580],"parameters":{"options":{"responseCode":200},"respondWith":"noData"},"typeVersion":1.1,"notes":"This respondToWebhook node performs automated tasks as part of the workflow."},{"id":"273dfd58-abef-49b7-8f12-5abc3d3515a6","name":"single workflow","type":"n8n-nodes-base.webhook","position":[240,240],"webhookId":"135bc21f-c7d0-4afe-be73-f984d444b43b","parameters":{"path":"/:file","options":{},"responseMode":"responseNode","multipleMethods":true},"typeVersion":2,"notes":"This webhook node performs automated tasks as part of the workflow."},{"id":"a7d7ee50-1420-475b-9028-0c80e1ae2241","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[140,-242.54375384615383],"parameters":{"width":296.5956923076922,"height":277.9529846153844,"content":"## Main Docsify webhook\nIn response, n8n serves the main html page with the [Docsify JS library]({{ $env.WEBHOOK_URL }}"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"b7c4b82a-9722-48ae-ab6a-4335981356ad","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-77.62340912473337,108.96056004923076],"parameters":{"width":509.1040245093486,"height":287.9568584558579,"content":"## Single page requests\n* Docsify may request default pages (i.e. `readme.md` or a `summary.md`)\n* GET request for the workflow documentation pages\n* POST request for saving manually edited doc page"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"18e1f4c5-3652-4244-9a09-cd7a498a9310","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[460,-240.54580345183416],"parameters":{"color":3,"width":489.50636350106504,"height":462.9720128227216,"content":"## EDIT THIS!\n* `project_path` to link to a writable directory that is accessible to n8n\n* update `instance_url` when running in the cloud version. If using in self-hosted mode, make sure N8N_PROTOCOL and N8N_HOST .env variables are correct"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"d505d2ec-33e9-4983-8265-ff55f0df3da8","name":"file types","type":"n8n-nodes-base.switch","position":[1180,240],"parameters":{"rules":{"values":[{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"endsWith"},"leftValue":"={{ $json.params.file.toLowerCase() }}","rightValue":".md"}]},"renameOutput":true}]},"options":{"fallbackOutput":"extra","renameFallbackOutput":"unknown"}},"typeVersion":3.2,"notes":"This switch node performs automated tasks as part of the workflow."},{"id":"59362792-4a3e-4f97-95e2-d7b33b870e1d","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[4620,-245.7696645512633],"parameters":{"width":446.67466982248516,"height":309.89805271694365,"content":"## Construct main HTML page and send it back to the user\n* `HTML_headers` and `HTML_docsify_include` are stored in the CONFIG node for the page simplicity"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"83189146-4d1f-454e-9591-bdbfda676683","name":"Get All Workflows","type":"n8n-nodes-base.n8n","position":[1880,160],"parameters":{"filters":{"tags":"={{ decodeURIComponent(($json.params.file?.match(/^tag-(.+)\\.md$/))?.[1] || '') }}"},"requestOptions":{}},"credentials":{"n8nApi":{"id":"eW7IdTFt4ARJbEwR","name":"Ted n8n account"}},"typeVersion":1,"alwaysOutputData":true,"notes":"This n8n node performs automated tasks as part of the workflow."},{"id":"39aa6017-a0ef-4f05-81b8-cfc9bb2fcc20","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[1780,20.913927466176517],"parameters":{"width":820.1843305645202,"height":307.51990359708003,"content":"## Serve main Markdown table with the workflow overview\n*NOTE! Here we don't reply with HTML content. Only Markdown elements are sent back and processed by the JS library*\n* Create an overall table when `README.md` (the home page) is requested\n* Create a table with a subset of workflows when a tag from a navigation pane is selected"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"2d087c25-b998-4abc-b0ce-ede8e62e28b4","name":"md files","type":"n8n-nodes-base.switch","position":[1440,180],"parameters":{"rules":{"values":[{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.params.file }}","rightValue":"README.md"}]},"renameOutput":true},{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"c1c1aecc-8faa-47ea-b831-4674c3c0db61","operator":{"type":"string","operation":"contains"},"leftValue":"={{ $json.params.file }}","rightValue":"docs_"}]},"renameOutput":true},{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"fde643c9-31cd-4cbd-b4de-99a8ad6202af","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.params.file }}","rightValue":"summary.md"}]},"renameOutput":true},{"outputKey":"YOUR_CREDENTIAL_HERE","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"df4bc9f8-9285-49a6-b31c-d7173bf42901","operator":{"type":"string","operation":"startsWith"},"leftValue":"={{ $json.params.file }}","rightValue":"tag-"}]},"renameOutput":true}]},"options":{"fallbackOutput":"extra"}},"typeVersion":3.2,"notes":"This switch node performs automated tasks as part of the workflow."},{"id":"08524df2-d555-42ca-8440-57ca5a780b74","name":"Get Workflow tags","type":"n8n-nodes-base.n8n","position":[1880,500],"parameters":{"filters":{},"requestOptions":{}},"credentials":{"n8nApi":{"id":"eW7IdTFt4ARJbEwR","name":"Ted n8n account"}},"typeVersion":1,"notes":"This n8n node performs automated tasks as part of the workflow."},{"id":"06e383dc-b1ea-4c97-9ee4-c07084ffc4cc","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1780,360],"parameters":{"width":817.6163848212657,"height":288.20835077550953,"content":"## Serve left pane content\n* Here all workflows are fetched again when `summary.md` file is requested.\n\nIt contains Markdown for the left navigation pane: a list of all tags"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"c28ae282-7d83-42dd-8714-30d26b0f20af","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[1700,1780],"parameters":{"width":367.8950651848079,"height":262.5093167050718,"content":"## Handle missing pages\nServe the Markdown content with the requested file name for edge cases, i.e. any unexpected files"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"6441cf8f-dace-45fb-984e-aa9e0589e495","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[1020,729],"parameters":{"color":6,"width":4161.578473434268,"height":1142.0268674813442,"content":"# Main functionality here\n\n## * View existing documentation\n## * Auto-generate doc page if no file available\n## * Re-created autodoc page\n## * Edit doc page: LIVE Markdown editor included!\n## * Save edited file. WARNING! No authentication"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"9116a4eb-18c6-4ec2-84e8-9a0b920d5c19","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[4460,751],"parameters":{"width":652.3100890494833,"height":268.0620091282372,"content":"## Custom markdown editor\nThis is another HTML page for the live Markdown editor\n* `Mermaid.js` is supported\n* Docsify preview on edit\n* Save or Cancel buttons"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"920c1edb-29ad-4952-9e30-9020146ed88a","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[4000,1501],"parameters":{"width":522.870786668288,"height":348.0868581511653,"content":"## Save new file\nOnce the doc page is generated or edited manually, a Markdown files is saved in the directory"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"cff4d2be-f627-4c7d-9f7a-093f6f9b2c27","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[1887,758],"parameters":{"width":639.8696984316115,"height":429.7891698152571,"content":"## Load existing doc file\nCheck the existing file when the View or Edit button is pressed\n"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"b7f01785-99c7-47b2-967a-b7456bb8f562","name":"Sticky Note11","type":"n8n-nodes-base.stickyNote","position":[2786.9421822644376,1023],"parameters":{"width":1369.2986733206085,"height":466.42237140646773,"content":"## If the file is not available, then:\n* either auto-generate new doc\n* prepare a basic template for editing"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"6953bf0c-3122-4d80-9e74-1c07a892bf31","name":"docsify","type":"n8n-nodes-base.webhook","position":[240,-100],"webhookId":"8b719afe-8be3-4cd5-84ed-aca521b31a89","parameters":{"path":"135bc21f-c7d0-4afe-be73-f984d444b43b","options":{},"responseMode":"responseNode"},"typeVersion":2,"notes":"This webhook node performs automated tasks as part of the workflow."}],"active":true,"settings":{"callerPolicy":"workflowsFromSameOwner","executionOrder":"v1","executionTimeout":3600,"saveManualExecutions":true,"saveDataSuccessExecution":"all","errorWorkflow":null,"timezone":"UTC","maxExecutions":1000,"retryOnFail":true,"retryCount":3,"retryDelay":1000},"versionId":"eee9144a-c7a0-4947-874b-728d9e8618b7","connections":{"Respond with markdown":{"main":[[],[],[],[],[],[],[],[],[]]},"Respond with HTML":{"main":[[],[],[],[],[],[],[],[],[]]},"Respond with main page HTML":{"main":[[],[],[],[],[],[],[],[],[]]},"Respond OK on Save":{"main":[[],[],[],[],[],[],[],[],[]]},"single workflow":{"main":[[],[],[],[],[],[],[],[],[]]},"docsify":{"main":[[],[],[],[],[],[],[],[],[]]},"Convert to File":{"main":[[]]},"Extract from File":{"main":[[]]},"Load Doc File":{"main":[[]]},"Save New Doc File":{"main":[[]]},"OpenAI Chat Model":{"main":[[]]}},"description":"Automated workflow: Docsify example. This workflow integrates 21 different services: convertToFile, stickyNote, merge, switch, outputParserAutofixing. It contains 77 nodes and follows best practices for error handling and security.","notes":"Excellent quality workflow: Docsify example. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}