diff --git a/src/App.tsx b/src/App.tsx index 44e6d88..c40683b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,6 +12,7 @@ export default function App() { const [settings, setSettings] = useState(PresetOptions); + console.log(settings); return (
{ +export let ScanModule = ({ inputDisplayed, settings }) => { let [text, setText] = useState(""); - let lines = ScanParagraph(text, PresetOptions); + let lines = ScanParagraph(text, settings); let other = inputDisplayed === "in" ? "out" : "in"; diff --git a/src/components/Toolbar.tsx b/src/components/Toolbar.tsx index 4380251..9c55617 100644 --- a/src/components/Toolbar.tsx +++ b/src/components/Toolbar.tsx @@ -40,9 +40,16 @@ function SettingsButton({ settings, setSettings }) { function toggleOpen() { setOpen(!open); } + function toggleFirst() { + setSettings({ + ...settings, + first: settings.first === "Hexameter" ? "Pentameter" : "Hexameter", + }); + } + let meters = ["Hexameter", "Pentameter", "Elegaic"]; return ( -
+

{settings.meter}

@@ -52,6 +59,7 @@ function SettingsButton({ settings, setSettings }) { {meters.map((each) => { return (

{ setSettings({ @@ -68,6 +76,11 @@ function SettingsButton({ settings, setSettings }) {

)} + {settings.meter === "Elegaic" && ( + + )}
); } diff --git a/src/index.sass b/src/index.sass index 8149454..a7ed050 100644 --- a/src/index.sass +++ b/src/index.sass @@ -82,6 +82,10 @@ ul .toolbarButton:active background-color: #1a1a1a +.meterButton + display: flex + flex-direction: row + .meterOptions position: absolute max-width: 25% @@ -158,10 +162,11 @@ ul .line font-size: var(--fontSize) min-height: 2em - padding: 0 10px + padding: 10px margin: 0 display: flex flex-direction: column + border-bottom: black solid 1px .lineSelection diff --git a/src/scan.ts b/src/scan.ts index 1daac22..fd02891 100644 --- a/src/scan.ts +++ b/src/scan.ts @@ -1,6 +1,7 @@ //scan.ts import type { metaLine, + meter, quantity, scannedLineType, setting, @@ -27,13 +28,27 @@ import expressions, { export let ScanParagraph = (text: string, settings: setting) => { let lines = text.split("\n"); let done: scannedLineType[] = []; - for (let line of lines) { - done.push(scanLine(line, settings)); + + if (settings.meter === "Elegaic") { + let currentMeter = settings.first; + for (let line of lines) { + if (line !== "") { + done.push(scanLine(line, currentMeter)); + currentMeter = + currentMeter === "Hexameter" ? "Pentameter" : "Hexameter"; + } + } + } else { + for (let line of lines) { + if (line !== "") { + done.push(scanLine(line, settings.meter)); + } + } } return done; }; -export let scanLine = (line: string, settings: setting): scannedLineType => { +export let scanLine = (line: string, meter: meter): scannedLineType => { let output: scannedLineType = { line: line, raws: [], full: [] }; //initialize output object let meta: metaLine = undress(line); @@ -44,10 +59,10 @@ export let scanLine = (line: string, settings: setting): scannedLineType => { } output.raws = dressedRaws; - // now we would switch on settings.meter + // now we would switch on the meter let toDress: sylMap[][] = []; - switch (settings.meter) { - case "hexameter": + switch (meter) { + case "Hexameter": for (let each of raws) { let quantityScans = hexScan(each); let pos = Object.keys(each).map((elt) => { @@ -58,6 +73,19 @@ export let scanLine = (line: string, settings: setting): scannedLineType => { }); toDress.push(scans); } + break; + case "Pentameter": + for (let each of raws) { + let quantityScans = penScan(each); + let pos = Object.keys(each).map((elt) => { + return parseInt(elt); + }); + let scans = quantityScans.map((elt) => { + return marryUp(elt, pos); + }); + toDress.push(scans); + } + break; } let done: string[][] = toDress.map((rawGroup) => { @@ -215,6 +243,95 @@ export let postScan = (meta: metaLine, markings: sylMap): string => { return line.join(""); }; +/** function that takes a list of permutator outputs (4 binary arrays) and returns a list of complete quantity descriptions; 1 for each arr in the input. + * + * @param { number[][] } arr + * @returns { quantity[][] } + */ +export function arrToQuantity(arr: number[][], meter: meter): quantity[][] { + let output: quantity[][] = []; + for (let each of arr) { + let temp = each.map((el) => { + //first we map each 0 or 1 to an array of quantities. + return el === 0 //if the element is 0, then the foot is long + ? (["long", "long", "break"] as quantity[]) //so insert the long foot template + : (["long", "short", "short", "break"] as quantity[]); //else, insert the short foot template + }); + + //we have now an array of quantity arrays; (quantity[][]) + switch (meter) { + case "Hexameter": + temp.push([ + "long", + "short", + "short", + "break", + "long", + "undefined", + ] as quantity[]); + break; + case "Pentameter": + temp.push([ + "long", + "break", + "long", + "short", + "short", + "break", + "long", + "short", + "short", + "break", + "long", + ]); + break; + } + + //we then flatten this by concatenating all the inner lists + //resulting in a quant[] + let temp2 = temp.reduce((acc, val) => { + return acc.concat(val); + }); + + output.push(temp2); //push this to the list of meters + } + return output; +} + +/** utility function that marries up a list of quantities with a list of positions into a record/dictionary + * + * @param { quantity[] } quants + * @param { number [] } positions + * @returns { sylMap } + */ +export function marryUp(quants: quantity[], positions: number[]): sylMap { + let output: sylMap = {}; + let breaks = 0; + for (let i = 0; i < quants.length; i++) { + let curQuant = quants[i]; + let curPos: number; + if (curQuant === "break") { + breaks++; + curPos = positions[i - breaks] + 1; + } else { + curPos = positions[i - breaks]; + } + output[curPos] = curQuant; + } + return output; +} + +export let insertPunctuation = ( + line: string[], + markup: Record +): string[] => { + let positions = Object.keys(markup).map((el) => parseInt(el)); + for (let each of positions) { + line.splice(each, 0, markup[each]); + } + return line; +}; + /** * hexScan matches the possible scans to the known quantities * returns an array of objects @@ -267,7 +384,7 @@ export let hexScan = (map: sylMap): quantity[][] => { return meters; } - meters = arrToQuantity(generateHexCombos(dactyls)); + meters = arrToQuantity(generateHexCombos(dactyls), "Hexameter"); //create a copy of the meters without breaks let clone = meters.map((each) => { return each.filter((elt) => { @@ -293,72 +410,58 @@ export let hexScan = (map: sylMap): quantity[][] => { return meters; }; -/** function that takes a list of permutator outputs (4 binary arrays) and returns a list of complete quantity descriptions; 1 for each arr in the input. - * - * @param { number[][] } arr - * @returns { quantity[][] } - */ -export function arrToQuantity(arr: number[][]): quantity[][] { - let output: quantity[][] = []; - for (let each of arr) { - let temp = each.map((el) => { - //first we map each 0 or 1 to an array of quantities. - return el === 0 //if the element is 0, then the foot is long - ? (["long", "long", "break"] as quantity[]) //so insert the long foot template - : (["long", "short", "short", "break"] as quantity[]); //else, insert the short foot template - }); - - //we have now an array of quantity arrays; (quantity[][]) - temp.push([ - "long", - "short", - "short", - "break", - "long", - "undefined", - ] as quantity[]); +export let penScan = (map: sylMap): quantity[][] => { + function generatePenCombos(dactyls: number): number[][] { + switch (dactyls) { + case 0: + return [[0, 0]]; + case 1: + return [ + [0, 1], + [1, 0], + ]; + case 2: + return [[1, 1]]; + } + return [[0, 0]]; //the default case is to assume 0 dactyls + } + let quantValues = Object.values(map); //extract quantities array + let meters: quantity[][] = []; - //we then flatten this by concatenating all the inner lists - //resulting in a quant[] - let temp2 = temp.reduce((acc, val) => { - return acc.concat(val); - }); + //now, calculate the number of spondaic syllables + let vowels = quantValues.length; + let dactyls = vowels - 12; - output.push(temp2); //push this to the list of meters + //handle line too long or short cases + if (dactyls > 2) { + console.log("too long!"); + return meters; + } else if (dactyls < 0) { + console.log("too short!"); + return meters; } - return output; -} -/** utility function that marries up a list of quantities with a list of positions into a record/dictionary - * - * @param { quantity[] } quants - * @param { number [] } positions - * @returns { sylMap } - */ -export function marryUp(quants: quantity[], positions: number[]): sylMap { - let output: sylMap = {}; - let breaks = 0; - for (let i = 0; i < quants.length; i++) { - let curQuant = quants[i]; - let curPos: number; - if (curQuant === "break") { - breaks++; - curPos = positions[i - breaks] + 1; - } else { - curPos = positions[i - breaks]; + meters = arrToQuantity(generatePenCombos(dactyls), "Pentameter"); + //create a copy of the meters without breaks + let clone = meters.map((each) => { + return each.filter((elt) => { + return elt !== "break"; + }); + }); + let curQuant: quantity; + for (let vowelCounter = 0; vowelCounter < vowels; vowelCounter++) { + curQuant = quantValues[vowelCounter]; + if (curQuant !== "undefined") { + for (let meterCounter = 0; meterCounter < meters.length; meterCounter++) { + if (clone[meterCounter][vowelCounter] === "undefined") { + // do nothing. + } else if (clone[meterCounter][vowelCounter] !== curQuant) { + clone.splice(meterCounter, 1); + meters.splice(meterCounter, 1); + meterCounter--; + } + } } - output[curPos] = curQuant; - } - return output; -} - -export let insertPunctuation = ( - line: string[], - markup: Record -): string[] => { - let positions = Object.keys(markup).map((el) => parseInt(el)); - for (let each of positions) { - line.splice(each, 0, markup[each]); } - return line; + return meters; }; diff --git a/src/scanTypes.ts b/src/scanTypes.ts index 7719d56..16032b3 100644 --- a/src/scanTypes.ts +++ b/src/scanTypes.ts @@ -6,10 +6,11 @@ export type metaLine = { export type sylMap = Record; export type generalRecord = Record; -export type meter = "hexameter" | "pentameter" | "elegaic"; +export type meter = "Hexameter" | "Pentameter" | "Elegaic"; export type setting = { meter: meter; + first: meter; }; export type strictQuant = "long" | "short"; diff --git a/src/utils.ts b/src/utils.ts index 20f2194..f5bbbc1 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import type { vowel, quantity, strictQuant, setting } from "./scanTypes"; -export let PresetOptions: setting = { meter: "hexameter" }; +export let PresetOptions: setting = { meter: "Hexameter", first: "Hexameter" }; //regex expressions for constants to do with latin lanaguge export default {