Jumble text

This commit is contained in:
Mariusz Kaczmarczyk 2020-10-16 21:03:57 +02:00
parent eca1e1614b
commit 3ec2c8027e
5 changed files with 65 additions and 1 deletions

View file

@ -104,6 +104,7 @@ You can try `:help key` to know more about `key`. If it is an existing binding,
- `zi`/`zo`/`zz` — zoom in/out/reset zoom
- `<C-f>`/`<C-b>` — jump to the next/previous part of the page
- `g?` — Apply Caesar cipher to page (run `g?` again to switch back)
- `g!` — Jumble words on page
#### Find mode

View file

@ -129,7 +129,7 @@ import * as DOM from "@src/lib/dom"
import * as CommandLineContent from "@src/content/commandline_content"
import * as scrolling from "@src/content/scrolling"
import { ownTab } from "@src/lib/webext"
import { wrap_input, getLineAndColNumber, rot13_helper } from "@src/lib/editor_utils"
import { wrap_input, getLineAndColNumber, rot13_helper, jumble_helper } from "@src/lib/editor_utils"
import * as finding from "@src/content/finding"
import * as toys from "./content/toys"
import * as hinting from "@src/content/hinting"
@ -4363,6 +4363,23 @@ export function rot13(n: number) {
body.currentNode.textContent = rot13_helper(t, n)
}
}
/**
* Perform text jumbling (reibadailty).
*
* Shuffles letters except for first and last in all words in text nodes in the current tab. Only characters in
* the ASCII range are considered.
*
* Inspired by: https://www.newscientist.com/letter/mg16221887-600-reibadailty/
*/
//#content
export function jumble() {
const body = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, { acceptNode: node => NodeFilter.FILTER_ACCEPT })
while (body.nextNode()) {
const t = body.currentNode.textContent
body.currentNode.textContent = jumble_helper(t)
}
}
/**
* Hacky ex string parser.
*

View file

@ -239,6 +239,7 @@ export class default_config {
x: "stop",
gi: "focusinput -l",
"g?": "rot13",
"g!": "jumble",
"g;": "changelistjump -1",
J: "tabprev",
K: "tabnext",
@ -603,6 +604,7 @@ export class default_config {
prefremove: "removepref",
tabclosealltoright: "tabcloseallto right",
tabclosealltoleft: "tabcloseallto left",
reibadailty: "jumble",
}
/**

View file

@ -25,6 +25,7 @@ import {
getWordBoundaries,
wordAfterPos,
rot13_helper,
jumble_helper
} from "@src/lib/editor_utils"
/**
@ -403,3 +404,9 @@ export const rot13 = wrap_input((text, selectionStart, selectionEnd) => [
selectionStart,
null,
])
export const jumble = wrap_input((text, selectionStart, selectionEnd) => [
jumble_helper(text.slice(0, selectionStart) + text.slice(selectionEnd)),
selectionStart,
null,
])

View file

@ -292,3 +292,40 @@ export const charesar = (c: string, n = 13): string => {
return String.fromCharCode(((cn - 97 + n) % 26) + 97)
return c
}
/** @hidden
* Shuffles only letters except for the first and last letter in a word, where "word"
* is a sequence of one of: only lowercase letters OR 5 or more uppercase letters OR an uppercase letter followed
* by only lowercase letters.
*/
export const jumble_helper = (text: string): string => {
const wordSplitRegex = new RegExp("([^a-zA-Z]|[A-Z][a-z]+)")
return text.split(wordSplitRegex).map(jumbleWord).join("")
}
function jumbleWord(word: string): string {
if (word.length < 4 || isAcronym()) {
return word
}
const innerText = word.slice(1, -1)
return word.charAt(0) + shuffle(innerText) + word.charAt(word.length - 1)
function isAcronym() {
return word.length < 5 && word.toUpperCase() === word
}
}
/**
* Shuffles input string
* @param text string to be shuffled
*/
export const shuffle = (text: string): string => {
const arr = text.split("")
for (let i = arr.length - 1; i >= 0; i--) {
const j = Math.floor(Math.random() * i + 1)
const t = arr[i]
arr[i] = arr[j]
arr[j] = t
}
return arr.join("")
}