drakongen 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/.vscode/launch.json +18 -0
  2. package/LICENSE +24 -0
  3. package/README.md +80 -0
  4. package/browser/drakongen.js +1303 -0
  5. package/browsertest.html +84 -0
  6. package/buildbrowser +4 -0
  7. package/buildexamples.js +61 -0
  8. package/examples/00.Empty.drakon +1 -0
  9. package/examples/00.Empty.txt +5 -0
  10. package/examples/01. /320/221/320/265/320/273/321/213/320/270/314/206.drakon" +13 -0
  11. package/examples/01. /320/221/320/265/320/273/321/213/320/271.json" +16 -0
  12. package/examples/01. /320/221/320/265/320/273/321/213/320/271.txt" +4 -0
  13. package/examples/02. /320/247/320/265/314/210/321/200/320/275/321/213/320/270/314/206.drakon" +28 -0
  14. package/examples/02. /320/247/321/221/321/200/320/275/321/213/320/271.json" +31 -0
  15. package/examples/02. /320/247/321/221/321/200/320/275/321/213/320/271.txt" +10 -0
  16. package/examples/03. /320/241/320/265/321/200/321/213/320/270/314/206.drakon" +20 -0
  17. package/examples/03. /320/241/320/265/321/200/321/213/320/271.json" +23 -0
  18. package/examples/03. /320/241/320/265/321/200/321/213/320/271.txt" +6 -0
  19. package/examples/04. /320/221/321/203/321/200/321/213/320/270/314/206.drakon" +25 -0
  20. package/examples/04. /320/221/321/203/321/200/321/213/320/271.json" +29 -0
  21. package/examples/04. /320/221/321/203/321/200/321/213/320/271.txt" +7 -0
  22. package/examples/05. /320/226/320/265/314/210/320/273/321/202/321/213/320/270/314/206.drakon" +25 -0
  23. package/examples/05. /320/226/321/221/320/273/321/202/321/213/320/271.json" +29 -0
  24. package/examples/05. /320/226/321/221/320/273/321/202/321/213/320/271.txt" +7 -0
  25. package/examples/06. /320/221/320/260/320/263/321/200/320/276/320/262/321/213/320/270/314/206.drakon" +30 -0
  26. package/examples/06. /320/221/320/260/320/263/321/200/320/276/320/262/321/213/320/271.json" +35 -0
  27. package/examples/06. /320/221/320/260/320/263/321/200/320/276/320/262/321/213/320/271.txt" +10 -0
  28. package/examples/07. /320/244/320/270/320/276/320/273/320/265/321/202/320/276/320/262/321/213/320/270/314/206.drakon" +42 -0
  29. package/examples/07. /320/244/320/270/320/276/320/273/320/265/321/202/320/276/320/262/321/213/320/271.json" +49 -0
  30. package/examples/07. /320/244/320/270/320/276/320/273/320/265/321/202/320/276/320/262/321/213/320/271.txt" +14 -0
  31. package/examples/08. /320/221/320/270/321/200/321/216/320/267/320/276/320/262/321/213/320/270/314/206.drakon" +27 -0
  32. package/examples/08. /320/221/320/270/321/200/321/216/320/267/320/276/320/262/321/213/320/271.json" +27 -0
  33. package/examples/08. /320/221/320/270/321/200/321/216/320/267/320/276/320/262/321/213/320/271.txt" +6 -0
  34. package/examples/09. /320/236/321/200/320/260/320/275/320/266/320/265/320/262/321/213/320/270/314/206.drakon" +37 -0
  35. package/examples/09. /320/236/321/200/320/260/320/275/320/266/320/265/320/262/321/213/320/271.json" +39 -0
  36. package/examples/09. /320/236/321/200/320/260/320/275/320/266/320/265/320/262/321/213/320/271.txt" +10 -0
  37. package/examples/10. /320/240/320/276/320/267/320/276/320/262/321/213/320/270/314/206.drakon" +42 -0
  38. package/examples/10. /320/240/320/276/320/267/320/276/320/262/321/213/320/271.json" +54 -0
  39. package/examples/10. /320/240/320/276/320/267/320/276/320/262/321/213/320/271.txt" +16 -0
  40. package/examples/11. /320/227/320/260/321/211/320/270/321/202/320/275/321/213/320/270/314/206.drakon" +37 -0
  41. package/examples/11. /320/227/320/260/321/211/320/270/321/202/320/275/321/213/320/271.json" +39 -0
  42. package/examples/11. /320/227/320/260/321/211/320/270/321/202/320/275/321/213/320/271.txt" +10 -0
  43. package/examples/12. /320/221/320/276/320/273/320/276/321/202/320/275/321/213/320/270/314/206.drakon" +44 -0
  44. package/examples/12. /320/221/320/276/320/273/320/276/321/202/320/275/321/213/320/271.json" +43 -0
  45. package/examples/12. /320/221/320/276/320/273/320/276/321/202/320/275/321/213/320/271.txt" +10 -0
  46. package/examples/13. /320/241/320/260/320/273/320/260/321/202/320/276/320/262/321/213/320/270/314/206.drakon" +54 -0
  47. package/examples/13. /320/241/320/260/320/273/320/260/321/202/320/276/320/262/321/213/320/271.json" +63 -0
  48. package/examples/13. /320/241/320/260/320/273/320/260/321/202/320/276/320/262/321/213/320/271.txt" +18 -0
  49. package/examples/14. /320/227/320/276/320/273/320/276/321/202/320/276/320/270/314/206.drakon" +64 -0
  50. package/examples/14. /320/227/320/276/320/273/320/276/321/202/320/276/320/271.json" +73 -0
  51. package/examples/14. /320/227/320/276/320/273/320/276/321/202/320/276/320/271.txt" +22 -0
  52. package/examples/15. /320/241/320/270/320/275/320/270/320/270/314/206.drakon" +54 -0
  53. package/examples/15. /320/241/320/270/320/275/320/270/320/271.json" +87 -0
  54. package/examples/15. /320/241/320/270/320/275/320/270/320/271.txt" +26 -0
  55. package/examples/16. /320/223/320/276/320/273/321/203/320/261/320/276/320/270/314/206.drakon" +37 -0
  56. package/examples/16. /320/223/320/276/320/273/321/203/320/261/320/276/320/271.json" +48 -0
  57. package/examples/16. /320/223/320/276/320/273/321/203/320/261/320/276/320/271.txt" +13 -0
  58. package/examples/17. /320/241/320/260/320/273/320/260/321/202/320/276/320/262/321/213/320/270/314/206.drakon" +39 -0
  59. package/examples/17. /320/241/320/260/320/273/320/260/321/202/320/276/320/262/321/213/320/271.json" +41 -0
  60. package/examples/17. /320/241/320/260/320/273/320/260/321/202/320/276/320/262/321/213/320/271.txt" +10 -0
  61. package/examples/18. /320/241/321/202/320/260/320/273/321/214/320/275/320/276/320/270/314/206.drakon" +49 -0
  62. package/examples/18. /320/241/321/202/320/260/320/273/321/214/320/275/320/276/320/271.json" +67 -0
  63. package/examples/18. /320/241/321/202/320/260/320/273/321/214/320/275/320/276/320/271.txt" +19 -0
  64. package/examples/19. Lilla.drakon +39 -0
  65. package/examples/19. Lilla.json +45 -0
  66. package/examples/19. Lilla.txt +11 -0
  67. package/examples/Adaptive design.drakon +116 -0
  68. package/examples/Adaptive design.json +153 -0
  69. package/examples/Adaptive design.txt +47 -0
  70. package/examples/And test.drakon +46 -0
  71. package/examples/And test.json +46 -0
  72. package/examples/And test.txt +10 -0
  73. package/examples/Arrow - double exit.drakon +41 -0
  74. package/examples/Arrow - double exit.json +62 -0
  75. package/examples/Arrow - double exit.txt +14 -0
  76. package/examples/Complex arrow.drakon +93 -0
  77. package/examples/Complex arrow.json +162 -0
  78. package/examples/Complex arrow.txt +43 -0
  79. package/examples/DoubleArrow.drakon +53 -0
  80. package/examples/DoubleArrow.json +86 -0
  81. package/examples/DoubleArrow.txt +18 -0
  82. package/examples/Find pointing nodes.drakon +104 -0
  83. package/examples/Find pointing nodes.json +137 -0
  84. package/examples/Find pointing nodes.txt +29 -0
  85. package/examples/How to tune PID on a quadcopter.drakon +488 -0
  86. package/examples/How to tune PID on a quadcopter.json +734 -0
  87. package/examples/How to tune PID on a quadcopter.txt +169 -0
  88. package/examples/Or test.drakon +47 -0
  89. package/examples/Or test.json +46 -0
  90. package/examples/Or test.txt +10 -0
  91. package/examples/Silhouette test 1.drakon +47 -0
  92. package/examples/Silhouette test 1.json +82 -0
  93. package/examples/Silhouette test 1.txt +24 -0
  94. package/examples/Work out action-check.drakon +30 -0
  95. package/examples/Work out action-check.json +45 -0
  96. package/examples/Work out action-check.txt +9 -0
  97. package/examples/Workout foreach.drakon +63 -0
  98. package/examples/Workout foreach.json +62 -0
  99. package/examples/Workout foreach.txt +14 -0
  100. package/examples/ar01.drakon +25 -0
  101. package/examples/ar01.json +40 -0
  102. package/examples/ar01.txt +7 -0
  103. package/examples/ar02.drakon +30 -0
  104. package/examples/ar02.json +45 -0
  105. package/examples/ar02.txt +10 -0
  106. package/examples/ar03.drakon +32 -0
  107. package/examples/ar03.json +44 -0
  108. package/examples/ar03.txt +7 -0
  109. package/examples/ar04.drakon +37 -0
  110. package/examples/ar04.json +49 -0
  111. package/examples/ar04.txt +10 -0
  112. package/examples/ar05.drakon +37 -0
  113. package/examples/ar05.json +59 -0
  114. package/examples/ar05.txt +11 -0
  115. package/examples/ar06.drakon +40 -0
  116. package/examples/ar06.json +70 -0
  117. package/examples/ar06.txt +13 -0
  118. package/examples/ar07.drakon +40 -0
  119. package/examples/ar07.json +70 -0
  120. package/examples/ar07.txt +13 -0
  121. package/examples/ar08.drakon +47 -0
  122. package/examples/ar08.json +81 -0
  123. package/examples/ar08.txt +16 -0
  124. package/examples/ar09.drakon +52 -0
  125. package/examples/ar09.json +87 -0
  126. package/examples/ar09.txt +17 -0
  127. package/examples/ar10.drakon +52 -0
  128. package/examples/ar10.json +88 -0
  129. package/examples/ar10.txt +18 -0
  130. package/examples/ar11.drakon +47 -0
  131. package/examples/ar11.json +82 -0
  132. package/examples/ar11.txt +17 -0
  133. package/examples/ar12.drakon +37 -0
  134. package/examples/ar12.json +49 -0
  135. package/examples/ar12.txt +10 -0
  136. package/examples/getToken.drakon +76 -0
  137. package/examples/getToken.json +88 -0
  138. package/examples/getToken.txt +41 -0
  139. package/examples/tmp.drakon +49 -0
  140. package/examples/tmp.json +82 -0
  141. package/examples/tmp.txt +37 -0
  142. package/package.json +21 -0
  143. package/prompts/drakonToPrompt.txt +139 -0
  144. package/prompts/index.txt +17 -0
  145. package/prompts/printPseudo.txt +116 -0
  146. package/src/browserTools.js +39 -0
  147. package/src/drakonToPromptStruct.js +44 -0
  148. package/src/drakonToStruct.js +416 -0
  149. package/src/drakongen.js +16 -0
  150. package/src/index.js +17 -0
  151. package/src/main.js +157 -0
  152. package/src/nodeTools.js +38 -0
  153. package/src/printPseudo.js +167 -0
  154. package/src/structFlow.js +382 -0
  155. package/src/technicalTree.js +84 -0
  156. package/src/tools.js +36 -0
  157. package/src/translate.js +108 -0
package/src/main.js ADDED
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+
3
+ const {toTree, toPseudocode} = require("./index")
4
+
5
+ const fs = require('fs').promises;
6
+ const path = require('path');
7
+
8
+ // Display usage summary
9
+ function displayUsage() {
10
+ console.log(`Usage:
11
+ drakongen <path> Read from <path> and output to standard output
12
+ drakongen --language <lang> <path> Read from <path> and output to standard output, use the provided language
13
+ drakongen --tree <path> Read from <path> and output to standard output, use the JSON-tree format
14
+ drakongen --output <output folder> <path>
15
+ Read from <path> and write to <output folder>
16
+ drakongen Display this usage summary.`);
17
+ }
18
+
19
+
20
+
21
+ // Main logic
22
+ async function main() {
23
+ const args = process.argv.slice(2);
24
+
25
+ if (args.length === 0) {
26
+ displayUsage();
27
+ return;
28
+ }
29
+
30
+ let options = {
31
+ language: "en",
32
+ json: false,
33
+ output: null,
34
+ tree: false
35
+ };
36
+ let targetPath = null;
37
+
38
+ for (let i = 0; i < args.length; i++) {
39
+ switch (args[i]) {
40
+ case '--language':
41
+ options.language = args[++i];
42
+ break;
43
+ case '--tree':
44
+ options.tree = true;
45
+ break;
46
+ case '--output':
47
+ options.output = args[++i];
48
+ break;
49
+ default:
50
+ if (!targetPath) {
51
+ targetPath = args[i];
52
+ }
53
+ }
54
+ }
55
+
56
+ if (!targetPath) {
57
+ displayUsage();
58
+ return;
59
+ }
60
+
61
+ try {
62
+ const stats = await fs.lstat(targetPath);
63
+
64
+ if (stats.isDirectory()) {
65
+ await generate(targetPath, options);
66
+ } else {
67
+ await generateOne(targetPath, options);
68
+ }
69
+ } catch (err) {
70
+ console.error(`${err.message}`);
71
+ console.error(`Filename: ${err.filename}`);
72
+ console.error(`Node id: ${err.nodeId}`);
73
+ process.exit(1);
74
+ }
75
+ }
76
+
77
+ async function getDrakonFiles(dirPath) {
78
+ // Read all entries in the directory
79
+ const files = await fs.readdir(dirPath, { withFileTypes: true });
80
+
81
+ // Filter files that are regular files and have a .txt extension, then map to full paths
82
+ const txtFiles = files
83
+ .filter(file => file.isFile() && path.extname(file.name) === '.drakon')
84
+ .map(file => path.join(dirPath, file.name));
85
+
86
+ return txtFiles;
87
+ }
88
+
89
+ // Placeholder functions (not implemented)
90
+ async function generate(folderPath, options) {
91
+ var files = await getDrakonFiles(folderPath)
92
+ var output
93
+ if (options.tree) {
94
+ var obj = {procedures:[]}
95
+ for (var file of files) {
96
+ var json = await convertToTree(file, options)
97
+ obj.procedures.push(json)
98
+ }
99
+ output = JSON.stringify(obj, null, 4)
100
+ } else {
101
+ output = ""
102
+ for (var file of files) {
103
+ var pseudo = await convertToPseudo(file, options)
104
+ output += (pseudo + "\n\n\n")
105
+ }
106
+ }
107
+ await writeOut(output, folderPath, options.output)
108
+ }
109
+
110
+ async function generateOne(filePath, options) {
111
+ var output
112
+ if (options.tree) {
113
+ var json = await convertToTree(filePath, options)
114
+ output = JSON.stringify(json, null, 4)
115
+ } else {
116
+ output = await convertToPseudo(filePath, options)
117
+ }
118
+ await writeOut(output, filePath, options.output)
119
+ }
120
+
121
+ async function writeOut(content, inputPath, outputFolder) {
122
+ if (outputFolder) {
123
+ var pname = path.parse(inputPath)
124
+ var fullName = path.join(outputFolder, pname.name + ".txt")
125
+ await fs.writeFile(fullName, content, 'utf8');
126
+ } else {
127
+ console.log(content)
128
+ }
129
+ }
130
+
131
+ async function convertToTree(filePath, options) {
132
+ // Read the content of the file with UTF-8 encoding
133
+ const content = await fs.readFile(filePath, 'utf8');
134
+
135
+ var pname = path.parse(filePath)
136
+ const name = pname.name
137
+ var result = toTree(content, name, filePath, options.language)
138
+ return JSON.parse(result)
139
+ }
140
+
141
+
142
+ async function convertToPseudo(filePath, options) {
143
+ // Read the content of the file with UTF-8 encoding
144
+ const content = await fs.readFile(filePath, 'utf8');
145
+
146
+ var pname = path.parse(filePath)
147
+ const name = pname.name
148
+ const result = toPseudocode(content, name, filePath, options.language);
149
+ return result
150
+ }
151
+
152
+
153
+
154
+ // Entry point
155
+ main();
156
+
157
+
@@ -0,0 +1,38 @@
1
+ const { parse } = require('node-html-parser');
2
+
3
+
4
+ function htmlToString(html) {
5
+ if (!html) return '';
6
+ if (!html.startsWith('<') || !html.endsWith('>')) {
7
+ return html.split("\n").map(line => {return line.trim()})
8
+ }
9
+
10
+ const root = parse(html);
11
+ const output = [];
12
+
13
+ root.childNodes.forEach((node) => {
14
+ if (node.tagName === 'P') {
15
+ output.push(node.text.trim());
16
+ } else if (node.tagName === 'UL') {
17
+ output.push('');
18
+ node.childNodes.forEach((item) => {
19
+ if (item.tagName === 'LI') {
20
+ output.push(`- ${item.text.trim()}`);
21
+ }
22
+ });
23
+ output.push('');
24
+ } else if (node.tagName === 'OL') {
25
+ output.push('');
26
+ node.childNodes.forEach((item, index) => {
27
+ if (item.tagName === 'LI') {
28
+ output.push(`${index + 1}. ${item.text.trim()}`);
29
+ }
30
+ });
31
+ output.push('');
32
+ }
33
+ });
34
+
35
+ return output;
36
+ }
37
+
38
+ module.exports = {htmlToString}
@@ -0,0 +1,167 @@
1
+ var {addRange} = require("./tools")
2
+
3
+ function printPseudo(algorithm, translate, output, htmlToString) {
4
+
5
+
6
+
7
+ function printStructuredContent(content, indent, output) {
8
+ var lines = printStructuredContentNoIdent(content)
9
+ printWithIndent(lines, indent, output)
10
+ }
11
+
12
+ function printWithIndent(lines, indent, output) {
13
+ lines.forEach(line => output.push(indent + line))
14
+ }
15
+
16
+ function printStructuredContentNoIdent(content) {
17
+ var lines = []
18
+
19
+ if (typeof content === "string") {
20
+ return htmlToString(content);
21
+ } else if (content.operator === "not") {
22
+ lines = printStructuredContentNoIdent(content.operand)
23
+ if (lines.length > 0) {
24
+ lines[0] = translate("not") + " (" + lines[0] + ")"
25
+ }
26
+ } else if (content.operator === "and" || content.operator === "or") {
27
+ var operator = translate(content.operator)
28
+ printBinary(content, operator, lines)
29
+ } else if (content.operator === "equal") {
30
+ var operator = "=="
31
+ printBinary(content, operator, lines)
32
+ }
33
+
34
+ return lines;
35
+ }
36
+
37
+ function printBinary(content, operator, lines) {
38
+ const leftLines = printOperand(content.left);
39
+ const rightLines = printOperand(content.right);
40
+ if (leftLines.length === 1 && rightLines.length === 1) {
41
+ lines.push(leftLines[0] + " " + operator + " " + rightLines[0])
42
+ } else {
43
+ addRange(lines, leftLines)
44
+ lines.push(operator);
45
+ addRange(lines, rightLines)
46
+ }
47
+ }
48
+
49
+ function printOperand(content) {
50
+ var lines = printStructuredContentNoIdent(content)
51
+ if (typeof content === "string" || content.operator === "not") {
52
+ return lines
53
+ }
54
+ if (lines.length > 0) {
55
+ lines[0] = "(" + lines[0]
56
+ last = lines.length - 1
57
+ lines[last] = lines[last] + ")"
58
+ }
59
+ return lines
60
+ }
61
+
62
+ function makeIndent(depth) {
63
+ return " ".repeat(depth * 4);
64
+ }
65
+
66
+ function printSteps(steps, depth, output) {
67
+ const indent = makeIndent(depth)
68
+ for (var step of steps) {
69
+ if (step.type === "end" || step.type === "branch" || step.type === "comment") { continue }
70
+ if (step.type === "question") {
71
+ printQuestion(step, depth, output)
72
+ } else if (step.type === "loop") {
73
+ printLoop(step, depth, output)
74
+ } else if (step.type === "address") {
75
+ printAddress(step, indent, output)
76
+ } else if (step.type === "error") {
77
+ printError(step, indent, output)
78
+ } else if (step.type === "break") {
79
+ output.push(indent + translate("break"))
80
+ } else {
81
+ printOther(step, indent, output)
82
+ }
83
+ }
84
+ }
85
+
86
+ function printOther(step, indent, output) {
87
+ if (!step.content && !step.secondary) {return}
88
+ if (step.secondary) {
89
+ printStructuredContent(step.secondary, indent, output)
90
+ }
91
+ if (step.content) {
92
+ printStructuredContent(step.content, indent, output)
93
+ }
94
+ output.push("")
95
+ }
96
+
97
+ function printAddress(step, indent, output) {
98
+ var label
99
+ if (step.content) {
100
+ label = htmlToString(step.content);
101
+ } else {
102
+ label = translate("Subroutine") + " " + step.branch
103
+ }
104
+ output.push(indent + translate("Call subroutine") + " \"" + label + "\"")
105
+ }
106
+
107
+ function printError(step, indent, output) {
108
+ output.push(indent + translate("error") + ":")
109
+ output.push(indent + step.message)
110
+ if (step.content) {
111
+ printStructuredContent(step.content, indent, output)
112
+ }
113
+ output.push("")
114
+ }
115
+
116
+ function empty(array) {
117
+ return array.length === 0
118
+ }
119
+
120
+ function printQuestion(step, depth, output) {
121
+ const indent = makeIndent(depth)
122
+ const indent2 = makeIndent(depth + 1)
123
+ var yesBody = []
124
+ printSteps(step.yes, depth + 1, yesBody)
125
+ var noBody = []
126
+ printSteps(step.no, depth + 1, noBody)
127
+ if (empty(yesBody) && empty(noBody)) {
128
+ yesBody.push(indent2 + translate("pass"))
129
+ }
130
+ var content = step.content
131
+ if (empty(yesBody)) {
132
+ content = {operator:"not",operand:step.content}
133
+ }
134
+ var lines = printStructuredContentNoIdent(content)
135
+ lines[0] = translate("if") + " " + lines[0]
136
+ printWithIndent(lines, indent, output)
137
+ if (empty(yesBody)) {
138
+ addRange(output, noBody)
139
+ } else {
140
+ addRange(output, yesBody)
141
+ if (!empty(noBody)) {
142
+ output.push(indent + translate("else"))
143
+ addRange(output, noBody)
144
+ }
145
+ }
146
+ }
147
+
148
+ function printLoop(step, depth, output) {
149
+ const indent2 = makeIndent(depth + 1)
150
+ const indent = makeIndent(depth)
151
+ var body = []
152
+ printSteps(step.body, depth + 1, body)
153
+ if (empty(body)) {
154
+ body.push(indent2 + translate("pass"))
155
+ }
156
+ var content = step.content
157
+ if (!content) {
158
+ content = translate("loop forever")
159
+ }
160
+ printStructuredContent(content, indent, output)
161
+ addRange(output, body)
162
+ }
163
+
164
+ printSteps(algorithm.body, 0, output)
165
+ }
166
+
167
+ module.exports = {printPseudo}