Clean up personal statement code
authoradrianiainlam <adrianiainlam@gmail.com>
Tue, 12 Jul 2016 16:15:53 +0000 (00:15 +0800)
committeradrianiainlam <adrianiainlam@gmail.com>
Tue, 12 Jul 2016 16:15:53 +0000 (00:15 +0800)
index.html [new file with mode: 0644]
script.js [new file with mode: 0644]
style.css [new file with mode: 0644]

diff --git a/index.html b/index.html
new file mode 100644 (file)
index 0000000..d46a01c
--- /dev/null
@@ -0,0 +1,99 @@
+<!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 &amp; 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 &amp; 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
+        &lt;<a href="mailto:ail30@cam.ac.uk">ail30@cam.ac.uk</a>&gt;.
+      </address>
+      <footer>
+        <p>Copyright &copy; 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>
diff --git a/script.js b/script.js
new file mode 100644 (file)
index 0000000..a90ac30
--- /dev/null
+++ b/script.js
@@ -0,0 +1,63 @@
+$ = 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';
+    }
+}
diff --git a/style.css b/style.css
new file mode 100644 (file)
index 0000000..48c1907
--- /dev/null
+++ b/style.css
@@ -0,0 +1,35 @@
+#txt1 {
+    font-family: "Liberation Serif", "Times New Roman", serif;
+    width: 100%;
+    padding-left: 1em;
+    padding-right: 1em;
+    height: 15em;
+    box-sizing: border-box;
+}
+.topPadding {
+    padding-top: 12pt;
+}
+#resultsContainer {
+    font-family: monospace;
+    float: right;
+    min-width: 100ch;
+    border-left-style: solid;
+    border-left-width: 1px;
+    border-left-color: black;
+    box-sizing: border-box;
+    white-space: nowrap;
+}
+#statContainer {
+    overflow: auto;
+    padding-right: 8pt;
+}
+span.note {
+    font-size: 8pt;
+}
+footer {
+    font-size: 8pt;
+}
+.hidden {
+    visibility: hidden;
+}
+