Fix text length

by enagu

HTML

<html>
<body>
<h1>
Max Length
</h1>
<p style="width: 50%">
<input type="number" min="20" max="150" id="maxcn" value="40" style="width:40px"/>
<input type="range" min="20" max="150" id="maxcr" value="40" style="width:80%"/>
</p>

<p style="width: 50%">
<input type="checkbox" id="padding" />
<label for="padding">Add padding for list item</label>

<input type="checkbox" id="respect_newline" />
<label for="respect_newline">Respect existing new lines</label>


<input type="checkbox" checked id="replace-dash" />
<label for="replace-dash">Replace dash-ed words</label>
</p>

<h1>
Enter text
</h1>
<textarea id="text" cols="2" rows="6" style="width:80%"> </textarea>

<p>
<tt id="result"></tt>
</p>

<p>

<button onclick="copyResult">
Copy result
</button>
</p>

</body>
</html>

CSS

html,body, * {
  background-color: #000;
  color: #fff;
  font-family: monospace;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;

}

JavaScript

var elText = document.getElementById("text");
var elResult = document.getElementById("result");
var elMaxcr = document.getElementById("maxcr");
var elMaxcn  = document.getElementById("maxcn");
var elRespectNewLine  = document.getElementById("respect_newline");
var elReplaceDash  = document.getElementById("replace-dash");

const getNextLine = (text,maxL) => {
  var maxC = parseInt(maxL);
  var spaces = [...text.matchAll(/ /g)].map(r => r.index)
  var closestSpace = Math.max(...spaces.filter(r => r <= maxC));
  
  if (spaces.length == 0 || text.length < maxC) return {text, length: text.length};
  
  return {text: text.slice(0, closestSpace).trim(), length: closestSpace};
}

const getText = (text,maxL, padding) => {
		if (text.length <= maxL) return text;
    
    var result = "";
    var total = 0;
    var t = 500;
    var pad = " ".repeat(padding);
    //debugger;
    do {
    	var line = getNextLine(text.slice(total), maxL);
      
      if (result.length > 0 && padding > 0) {
       result += pad;
      }
      
      result += line.text + "\n";
      total += line.length;
    } while(text.length > total && t-- > 0);
    
    return result;
}

const computeParagraph = (text, maxL) => {
  var padding = 0;
  if (!isNaN(parseInt(text.at(0))) && text.match(/\d+/)) {
  	padding = text.match(/\d+/)[0].length + 1;
  }
  
  var rr = getText(text, maxL, padding).trim();
	return rr;
}

const computeText = (maxL) => {
  var text = elText.value.trim();
  
  if (elReplaceDash.checked) {
  	text = text.replaceAll(/(\w)-\s(\w)/g, "$1$2");
  }
  
	if (!elRespectNewLine.checked){
    var paragraph = text.replaceAll("\n", " ").replaceAll(/\s+/g, " ");
  	result.innerText = computeParagraph(paragraph, maxL);
  } else {
		var paragraphs = text.split("\n");
    var pr = paragraphs.map(t => computeParagraph(t, maxL));
    result.innerText = pr.join("\n");
  }
  
}

elMaxcr.oninput = (e) => {
	computeText(e.target.value);
  elMaxcn.value = e.target.value;
  
 ...