--- /dev/null
+<!DOCTYPE html>
+<html>
+<!--
+UCAS Personal Statement Word Counter
+Copyright (c) 2014-2016 Adrian Iain Lam
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+A copy of the GNU General Public License can be found at
+<http://www.gnu.org/licenses/gpl.html>.
+
+Contact: <ail30@cam.ac.uk>
+-->
+<head>
+ <title>UCAS Personal Statement Line & Character Counter</title>
+ <meta charset="utf-8" />
+ <meta
+ name="description"
+ content="
+ Confused by UCAS's way of counting lines and characters?
+ Click here for a detailed analysis.
+ "
+ />
+ <meta
+ name="keywords"
+ content="UCAS,line,word,character,count,counter,number,personal,statement"
+ />
+ <meta name="author" content="Adrian Iain Lam" />
+ <script src="script.js"></script>
+ <link rel="stylesheet" type="text/css" href="style.css" />
+</head>
+<body onload="autocheck()">
+ <h3>UCAS Personal Statement Line & Character Counter</h3>
+ <div id="txtContainer">
+ Paste your personal statement here!<br />
+ <textarea id="txt1"></textarea>
+ </div>
+
+ <div id="outputContainer" class="topPadding">
+ <div id="resultsContainer">
+ <div id="results"></div>
+ <!-- Empty div will not have space reserved -->
+ <div id="workaround" class="hidden">.</div>
+ </div>
+
+ <div id="statContainer">
+ <input id="chk1" type="checkbox" onclick="autocheck()" checked>
+ Automatic analysis
+ <span class="note">(Not recommended for slow computers)</span>
+ <button id="btn1" class="hidden" onclick="analyse()">
+ Analyse
+ </button>
+ <br />
+ <input id="chk2" type="checkbox" onclick="analyse()" checked>
+ Separate paragraphs
+ <br />
+ <span class="note">
+ (For readability purpose only. Will NOT be present in the UCAS
+ submission)
+ </span>
+ <div id="stats" class="topPadding">
+ <div id="statLines">Lines: 0/47</div>
+ <div id="statChars">Characters: 0/4000</div>
+ <div id="statWarn" class="hidden">
+ Warning: Extra space(s) found at end of paragraph(s)
+ </div>
+ </div>
+ <address>
+ Found a bug? Please report to
+ <<a href="mailto:ail30@cam.ac.uk">ail30@cam.ac.uk</a>>.
+ </address>
+ <footer>
+ <p>Copyright © 2014-2016 Adrian Iain Lam</p>
+ <p>
+ This program is free software, and you are welcome to redistribute it
+ under the terms of the GNU GPL. This program comes with ABSOLUTELY NO
+ WARRANTY. View the source for details.
+ </p>
+ <p>
+ This site is not affiliated with, endorsed by, approved by,
+ or related to UCAS.
+ </p>
+ <p>
+ Unlike <a href="http://maccery.com/ps/" target="_blank">the counter
+ by Maccery</a>, no personal statements are sent to the hosting server.
+ All codes are executed on the client-side.
+ </p>
+ </div>
+ </div>
+</body>
+</html>
--- /dev/null
+$ = document.getElementById.bind(document);
+function printStats(lines, numLines, numChars, parasWithExtraSpace, parasLines) {
+ $("results").innerHTML="";
+ for(var i=0; i<numLines; i++) {
+ $("results").innerHTML+=(i<9?"0"+(i+1):(i+1))+" "+lines[i]+"<br />";
+ if(parasLines.indexOf(i+1)>=0 && $("chk2").checked) $("results").innerHTML+="<br />";
+ }
+
+ $("statLines").innerHTML="Lines: "+numLines+"/47";
+ $("statLines").style.color=numLines>47?"red":"initial";
+ $("statChars").innerHTML="Characters: "+numChars+"/4000";
+ $("statChars").style.color=numChars>4000?"red":"initial";
+
+ if(parasWithExtraSpace.length>0) {
+ $("statWarn").innerHTML="Warning: Extra space(s) found at end of paragraph(s) "+parasWithExtraSpace.join(", ");
+ $("statWarn").style.visibility="visible";
+ $("statWarn").style.color="red";
+ } else {
+ $("statWarn").innerHTML="Warning: Extra space(s) found at end of paragraph(s) ";
+ $("statWarn").style.visibility="hidden";
+ }
+}
+
+function analyse() {
+ var text=$("txt1").value;
+ var parasWithExtraSpace=[];
+ var parasLines=[];
+ var paras=text.split('\n');
+ var lines=[];
+ var line=""
+ if(text=="") {
+ printStats(lines, 0, 0, parasWithExtraSpace, parasLines);
+ return;
+ }
+ for(var i=0; i<paras.length; i++) {
+ if(paras[i][paras[i].length-1]==' ') parasWithExtraSpace.push(i+1);
+ do {
+ if(paras[i][0]==' ') paras[i]=paras[i].substring(1); //remove preceding space
+ line=paras[i].substring(0, paras[i].length>94?94:paras[i].length); //extract line of 94 chars or fewer
+ var lastidx=line.lastIndexOf(' ');
+ if(lastidx>=0) { //if there is a space in line
+ if(line.length<94) lastidx=line.length; //if it can contain whole line
+ } else lastidx=line.length;
+ if(paras[i][94]==' ') lastidx=94; //if extracted right before a space
+ paras[i] = line.substring(lastidx+1)+paras[i].substring(94); //remove extracted string (up to lastidx) from paras
+ line=line.substring(0, lastidx);
+ lines.push(line);
+ } while(paras[i]!="");
+ parasLines.push(lines.length); //lines where paragraphs end
+ }
+ printStats(lines, lines.length, text.length+paras.length-1, parasWithExtraSpace, parasLines);
+}
+
+function autocheck() {
+ if($("chk1").checked) {
+ $("txt1").addEventListener("input", analyse);
+ $("btn1").style.visibility='hidden';
+ analyse();
+ } else {
+ $("txt1").removeEventListener("input", analyse);
+ $("btn1").style.visibility='visible';
+ }
+}