| 774 | } |
| 775 | |
| 776 | function addInsertionPoints ({ code, originalCode, codeLanguage }) { |
| 777 | if (codeLanguage === 'javascript') { |
| 778 | // Add special arrow block to point out blocks ending with empty lines, indicating code should go there |
| 779 | code = code.replace(/\n( {4,})\n([ ]*\})/gm, (_, s, s2) => `${s}\n__arrow__()${s2}`) |
| 780 | } |
| 781 | |
| 782 | // Add special arrow block to point out code insertion points after comments (only after intro comment section end) |
| 783 | const codeLines = code.split('\n') |
| 784 | const originalLines = originalCode.split('\n') |
| 785 | let newCode = '' |
| 786 | let previousLine = null |
| 787 | let previousLineHadComment = false |
| 788 | let previousLineHadCode = false |
| 789 | let previousLineWasBlank = false |
| 790 | let pastIntroComments = false |
| 791 | const commentStart = { javascript: '//', python: '#', lua: '--' }[codeLanguage] || '//' |
| 792 | const singleLineCommentRegex = new RegExp(`[ \t]*(${commentStart})[^"'\n]*`) |
| 793 | |
| 794 | for (let i = 0; i < codeLines.length; ++i) { |
| 795 | const line = codeLines[i] |
| 796 | const originalLine = originalLines[i] |
| 797 | // Find whether the line has changed. It might just be that the line was shifted around by the player inserting more code. |
| 798 | // We also look for the unchanged comment line in a new position to find what line we're really on. |
| 799 | const originalLineMovedIndex = originalLines.indexOf(previousLine) |
| 800 | const lineHasComment = singleLineCommentRegex.test(line) |
| 801 | const lineHasChanged = line !== originalLine && (originalLineMovedIndex === -1 || line !== originalLines[originalLineMovedIndex]) |
| 802 | const lineIsBlank = !line.trim()[0] |
| 803 | const lineHasCode = !lineIsBlank && !lineHasComment |
| 804 | if (lineHasCode || previousLineWasBlank) { |
| 805 | pastIntroComments = true |
| 806 | } |
| 807 | const isEntryPoint = lineIsBlank && previousLineHadComment && !previousLineHadCode && pastIntroComments && !lineHasChanged |
| 808 | if (isEntryPoint) { |
| 809 | newCode += line + '__arrow__()\n' |
| 810 | } else { |
| 811 | newCode += line + '\n' |
| 812 | } |
| 813 | previousLine = line |
| 814 | previousLineHadComment = lineHasComment |
| 815 | previousLineHadCode = lineHasCode |
| 816 | previousLineWasBlank = lineIsBlank |
| 817 | pastIntroComments = pastIntroComments || lineHasCode || previousLineWasBlank |
| 818 | } |
| 819 | return newCode |
| 820 | } |
| 821 | |
| 822 | function guardUnicode ({ code, codeLanguage }) { |
| 823 | if (!code) { return code } |