diff --git a/.gitignore b/.gitignore index c022ab1..9d14fb7 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ nosetests.xml # js ts_dist/ node_modules +web/ui.js diff --git a/package-lock.json b/package-lock.json index 50b0fdc..fc11483 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,14 @@ "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", "dev": true }, + "@types/jquery": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.0.tgz", + "integrity": "sha512-C7qQUjpMWDUNYQRTXsP5nbYYwCwwgy84yPgoTT7fPN69NH92wLeCtFaMsWeolJD1AF/6uQw3pYt62rzv83sMmw==", + "requires": { + "@types/sizzle": "*" + } + }, "@types/json-schema": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", @@ -60,6 +68,19 @@ "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", "dev": true }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==" + }, + "@types/typeahead": { + "version": "0.11.32", + "resolved": "https://registry.npmjs.org/@types/typeahead/-/typeahead-0.11.32.tgz", + "integrity": "sha512-5NkqKPwkBh2dGxFEJjc4Vt9/XsaGmx+tfXMfcJxWjPvCvvCFEKRCz+bz7ZfRAiO0e0Hh1foBol3anLzMY1Ea8A==", + "requires": { + "@types/jquery": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.5.0.tgz", @@ -1379,6 +1400,11 @@ "esutils": "^2.0.2" } }, + "dom": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/dom/-/dom-0.0.2.tgz", + "integrity": "sha1-4V+3WV4ym9Enj8yFjQ97jPOOS1E=" + }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -2807,9 +2833,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.17.tgz", + "integrity": "sha512-/B2DjOphAoqi5BX4Gg2oh4UR0Gy/A7xYAMh3aSECEKzwS3eCDEpS0Cals1Ktvxwlal3bBJNc+5W9kNIcADdw5Q==", "dev": true }, "log-symbols": { @@ -4480,6 +4506,22 @@ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, + "typeahead": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/typeahead/-/typeahead-0.2.2.tgz", + "integrity": "sha1-FADg8oLOZ9M5j8NKYu1eGCTFkps=", + "requires": { + "dom": "0.0.2", + "xtend": "1.0.3" + }, + "dependencies": { + "xtend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-1.0.3.tgz", + "integrity": "sha1-P12Tc1PM7Y4IU5mlY/2yJUHClgo=" + } + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", diff --git a/package.json b/package.json index a57ee76..78b8cd5 100644 --- a/package.json +++ b/package.json @@ -34,5 +34,9 @@ "typescript": "^3.9.6", "webpack": "^4.43.0", "webpack-cli": "^3.3.12" + }, + "dependencies": { + "@types/typeahead": "^0.11.32", + "typeahead": "^0.2.2" } } diff --git a/ts_src/ui.ts b/ts_src/ui.ts new file mode 100644 index 0000000..50adf67 --- /dev/null +++ b/ts_src/ui.ts @@ -0,0 +1,75 @@ +import {replacements} from './data'; +import {replace} from './replace'; + +const latexInput = $('#latexInput'); +const unicodeOutput = $('#unicodeOutput'); +const permaLink = $('.permalink'); + + +// copy replacements and sort case insensitive +var listOfReplacements = replacements + .map(function(r) { return { value: r[0], unicode: r[1] }; }) + .sort(function(a, b) { return a.value.toLowerCase().localeCompare(b.value.toLowerCase()); }); + +// reorder such that when just typing '\' suggestions starting with '\a' appear +var indexOfFirstA = listOfReplacements + .map(function(r) { return r.value.slice(0, 2).toLowerCase(); }) + .indexOf('\\a'); +listOfReplacements = listOfReplacements.slice(indexOfFirstA).concat(listOfReplacements.slice(0, indexOfFirstA)); + + +// Bloodhound: the source (dataset) for typeahead +var mySource = new Bloodhound({ + datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.value); }, + queryTokenizer: function(d) { var i = d.lastIndexOf('\\'); var r = [d.substr(0, i), d.substr(i)]; console.log(r); return r; }, + local: listOfReplacements, +}); +mySource.initialize(); + +// apply typeahead to input text field +latexInput.typeahead({ + hint: false, + highlight: true, + minLength: 0, +}, { + display: 'value', + source: mySource.ttAdapter(), + limit: 15, + templates: { + suggestion: function(datum: {unicode:string, value:string}) { + return '
Created by Sven Kreiss and Kyle Cranmer.
+ Maintained on GitHub.
+ +Tweet + + +
+ + + +Type LaTeX expressions in the input box on the left. The converted text in the box on the right can be copied to most programs including PowerPoint and Keynote, e-mail clients like Outlook and Mail and even apps on smart phones. UnicodeIt can create greek letters, arrows, mathematical symbols and many more for presentations, emails, chats, facebook, etc.
+ +x \in (-\infty, \infty) | x ∈ (-∞, ∞) | |
p\bar{p} \to \mu^+\mu^- | pp̅ → μ⁺μ⁻ | |
\alpha\omega\epsilon\S\om\in | αωε§øm∈ | |
^2H ^6Li ^{10}B ^{14}N | ²H ⁶Li ¹⁰B ¹⁴N | |
\mathcal{L} \mathcal{H} \mathbb{R} \mathbb{C} | ℒ ℋ ℝ ℂ |