-
Notifications
You must be signed in to change notification settings - Fork 282
Line Reader extension for TurboWarp #2193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
c6d1a4d
cd1b5cf
8264cac
6fffcb6
172afd0
db7e513
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,140 @@ | ||||||
// Name: Line Reader | ||||||
// ID: linereader | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ID should contain your username
Suggested change
|
||||||
// Description: A simple extension for reading newlines and supports special tilde delimiters. Use ~n for UNIX, ~r for Classic Mac OS, and ~z for Windows. | ||||||
// By: Pear Computer LLC. <https://scratch.mit.edu/users/-Microboy-/> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this a LLC? |
||||||
// License: BSD-2-Clause | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just out of curiosity wondering why you have special licensing, generally speaking this isn't necessary. Turbowarp recommends Mozilla Public License v2. See CONTRIBUTING.md. |
||||||
/* | ||||||
Copyright 2025 Pear Computer LLC. | ||||||
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | ||||||
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | ||||||
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | ||||||
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
*/ | ||||||
(function(Scratch) { | ||||||
"use strict"; | ||||||
|
||||||
class LineReaderExtension { | ||||||
getInfo() { | ||||||
return { | ||||||
id: 'linereader', // Unique ID for the extension | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This ID should also contain your username and be the same as the one in the header comment
Suggested change
|
||||||
name: 'Line Reader', // Name displayed in Scratch | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The lint is falling because you have a lot of translation errors. You should use Scratch.translate() on the extension name and block texts.
Suggested change
|
||||||
blocks: [ | ||||||
{ | ||||||
opcode: 'getLine', // Opcode for getting a specific line | ||||||
blockType: Scratch.BlockType.REPORTER, // It's a reporter block (returns a value) | ||||||
text: 'line [LINE_NUM] in [TEXT_INPUT]', // The text displayed on the block | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here and for the rest of the blocks. Also, I have to ask why you're using so many comments for things that should be obvious? It just distracts from the code |
||||||
arguments: { | ||||||
LINE_NUM: { | ||||||
type: Scratch.ArgumentType.NUMBER, // Argument for the line number | ||||||
defaultValue: 1 // Default value for the line number | ||||||
}, | ||||||
TEXT_INPUT: { | ||||||
type: Scratch.ArgumentType.STRING, // Argument for the multi-line text | ||||||
// Default value demonstrating different newline types using custom escape sequences | ||||||
defaultValue: 'Hello from UNIX!~nHello from Classic Mac!~rHello from Windows!~zFinal line.' | ||||||
} | ||||||
} | ||||||
} | ||||||
, | ||||||
{ | ||||||
opcode: 'countLines', // Opcode for counting lines | ||||||
blockType: Scratch.BlockType.REPORTER, // It's a reporter block (returns a number) | ||||||
text: 'number of lines in [TEXT_INPUT]', // The text displayed on the block | ||||||
arguments: { | ||||||
TEXT_INPUT: { | ||||||
type: Scratch.ArgumentType.STRING, // Argument for the multi-line text | ||||||
// Default value demonstrating different newline types using custom escape sequences | ||||||
defaultValue: 'First line!~nSecond line!~rThird line!~zFourth line.' | ||||||
} | ||||||
} | ||||||
} | ||||||
] | ||||||
}; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Helper function to process the input text by replacing custom escape sequences | ||||||
* with actual newline characters. | ||||||
* @param {string} text - The input string from a Scratch block. | ||||||
* @returns {string} The processed string with actual newlines. | ||||||
*/ | ||||||
_processNewlines(text) { | ||||||
// Ensure the input is treated as a string | ||||||
let processedText = String(text); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You shouldn't use JavaScript's native casting functions for block arguments as scratch has numerous odd quirks that could lead to issues. Use Scratch.Cast.toString() or Scratch.Cast.toNumber() for all block inputs.
Suggested change
|
||||||
|
||||||
// --- Pre-process custom newline escape sequences --- | ||||||
// It's crucial to replace the most specific (or potentially conflicting) | ||||||
// sequences first to avoid partial replacements. | ||||||
// Order: ~z (for \r\n), then ~r (for \r), then ~n (for \n) | ||||||
|
||||||
// ~z is for \r\n (Windows newline) | ||||||
processedText = processedText.replace(/~z/g, '\r\n'); | ||||||
// ~r is for \r (Classic Mac OS newline) | ||||||
processedText = processedText.replace(/~r/g, '\r'); | ||||||
// ~n is for \n (UNIX newline) | ||||||
processedText = processedText.replace(/~n/g, '\n'); | ||||||
|
||||||
return processedText; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Retrieves a specific line from a given string, automatically handling | ||||||
* common newline conventions and custom escape sequences. | ||||||
* @param {object} args - The arguments passed to the block. | ||||||
* @param {number} args.LINE_NUM - The 1-indexed line number to retrieve. | ||||||
* @param {string} args.TEXT_INPUT - The multi-line string to process. | ||||||
* @returns {string} The requested line, or an empty string if out of bounds. | ||||||
*/ | ||||||
getLine(args) { | ||||||
// Process custom escape sequences into actual newlines | ||||||
const processedText = this._processNewlines(args.TEXT_INPUT); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should also use casting, assuming it's a string it should probably look like this:
Suggested change
|
||||||
// Ensure the line number is an integer | ||||||
const lineNum = parseInt(args.LINE_NUM, 10); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This argument too and same goes for the rest of the args in every block |
||||||
|
||||||
// Regular expression to split by any common newline sequence: | ||||||
// \r\n (Windows) OR \r (Classic Mac) OR \n (UNIX) | ||||||
const linesArray = processedText.split(/\r\n|\r|\n/); | ||||||
|
||||||
// Scratch line numbers are 1-indexed, so convert to 0-indexed for JavaScript array | ||||||
const index = lineNum - 1; | ||||||
|
||||||
// Check if the requested line number is within the valid range | ||||||
if (index >= 0 && index < linesArray.length) { | ||||||
return linesArray[index]; // Return the requested line | ||||||
} else { | ||||||
return ''; // Return an empty string if the line number is out of bounds | ||||||
} | ||||||
} | ||||||
|
||||||
/** | ||||||
* Counts the number of lines in a given string, automatically handling | ||||||
* common newline conventions and custom escape sequences. | ||||||
* @param {object} args - The arguments passed to the block. | ||||||
* @param {string} args.TEXT_INPUT - The multi-line string to process. | ||||||
* @returns {number} The total number of lines in the string. | ||||||
*/ | ||||||
countLines(args) { | ||||||
// Process custom escape sequences into actual newlines | ||||||
const processedText = this._processNewlines(args.TEXT_INPUT); | ||||||
|
||||||
// Regular expression to split by any common newline sequence: | ||||||
// \r\n (Windows) OR \r (Classic Mac) OR \n (UNIX) | ||||||
const linesArray = processedText.split(/\r\n|\r|\n/); | ||||||
|
||||||
// If the input string is empty, split() will return [''], so length will be 1. | ||||||
// We want 0 lines for an empty string. | ||||||
if (processedText === '') { | ||||||
return 0; | ||||||
} | ||||||
return linesArray.length; | ||||||
} | ||||||
} | ||||||
|
||||||
// Register the extension with Scratch | ||||||
Scratch.extensions.register(new LineReaderExtension()); | ||||||
|
||||||
})(Scratch); // Pass the global Scratch object into the IIFE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not delete CNAME, it's what allows the custom domain name (extensions.turbowarp.org) to work