├── .github └── workflows │ └── gh-pages-publish.yml ├── .gitignore ├── README.md ├── elm.json ├── elmapp.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── icon.png ├── index.html ├── logo.svg └── manifest.json └── src ├── GithubLogo.elm ├── Main.elm ├── Math.elm ├── Ports.elm ├── assets ├── fonts │ ├── Changes │ ├── FAQ │ ├── FontLog.txt │ ├── Fontmap.CMU │ ├── INSTALL │ ├── OFL-FAQ.txt │ ├── OFL.txt │ ├── README │ ├── TODO │ ├── cmunbbx.ttf │ ├── cmunbi.ttf │ ├── cmunbl.ttf │ ├── cmunbmo.ttf │ ├── cmunbmr.ttf │ ├── cmunbso.ttf │ ├── cmunbsr.ttf │ ├── cmunbtl.ttf │ ├── cmunbto.ttf │ ├── cmunbx.ttf │ ├── cmunbxo.ttf │ ├── cmunci.ttf │ ├── cmunit.ttf │ ├── cmunobi.ttf │ ├── cmunobx.ttf │ ├── cmunorm.ttf │ ├── cmunoti.ttf │ ├── cmunrb.ttf │ ├── cmunrm.ttf │ ├── cmunsi.ttf │ ├── cmunsl.ttf │ ├── cmunso.ttf │ ├── cmunss.ttf │ ├── cmunssdc.ttf │ ├── cmunst.ttf │ ├── cmunsx.ttf │ ├── cmuntb.ttf │ ├── cmunti.ttf │ ├── cmuntt.ttf │ ├── cmuntx.ttf │ ├── cmunui.ttf │ ├── cmunvi.ttf │ ├── cmunvt.ttf │ └── fonts.scale └── main.css ├── components ├── InputMath.js └── StaticMath.js ├── index.js └── serviceWorker.js /.github/workflows/gh-pages-publish.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build-and-deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 🛎️ 13 | uses: actions/checkout@v3 14 | 15 | - name: Setup Elm 🌳 16 | uses: jorelali/setup-elm@v3 17 | with: 18 | elm-version: 0.19.1 19 | 20 | - name: Setup Node 21 | uses: actions/setup-node@v3 22 | with: 23 | node-version: "16.x" 24 | 25 | - name: Install Node Modules 26 | run: npm ci 27 | 28 | - name: Build 🏗️ 29 | run: npm run build 30 | 31 | - name: Deploy 🚀 32 | uses: JamesIves/github-pages-deploy-action@v4.4.0 33 | with: 34 | branch: gh-pages # The branch the action should deploy to. 35 | folder: build # The folder the action should deploy. 36 | # https://github.com/actions/checkout/discussions/479#discussioncomment-625461 37 | git-config-name: github-actions[bot] 38 | git-config-email: github-actions[bot]@users.noreply.github.com 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Distribution 2 | build/ 3 | 4 | # elm-package generated files 5 | elm-stuff 6 | 7 | # elm-repl generated files 8 | repl-temp-* 9 | 10 | # Dependency directories 11 | node_modules 12 | 13 | # Desktop Services Store on macOS 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Symbolic Derivatives 2 | 3 | This project, inspired by [this Haskell blog post](http://5outh.blogspot.com/2013/05/symbolic-calculus-in-haskell.html) aims to provide symbolic differentiation along with user friendly input and output, via [MathQuill](http://mathquill.com/). 4 | 5 | ## Demo 6 | 7 | [https://joshuaji.com/derivative](https://joshuaji.com/derivative) 8 | 9 | ## Run 10 | 11 | Make sure you have `Elm` and `Node` installed (at least v14). 12 | 13 | ```bash 14 | npm i 15 | npm run start 16 | ``` 17 | 18 | ## Credit 19 | 20 | Special thanks to: 21 | 22 | - Benjamin Kovach's [Symbolic Calculus in Haskell](http://5outh.blogspot.com/2013/05/symbolic-calculus-in-haskell.html), the blog post which inspired this project. 23 | 24 | - [MathQuill](http://mathquill.com/), for making it so easy manage LaTeX input and output. 25 | 26 | - [Create Elm App](https://github.com/halfzebra/create-elm-app), with which this project is bootstrapped. 27 | 28 | - The [Elm Pratt Parser](https://github.com/dmy/elm-pratt-parser) library - this project wouldn't be possible without this package. 29 | 30 | - [The Elm Language](https://elm-lang.org/), for being so easy to work with. 31 | -------------------------------------------------------------------------------- /elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | "src" 5 | ], 6 | "elm-version": "0.19.1", 7 | "dependencies": { 8 | "direct": { 9 | "dmy/elm-pratt-parser": "2.0.0", 10 | "elm/browser": "1.0.1", 11 | "elm/core": "1.0.2", 12 | "elm/html": "1.0.0", 13 | "elm/json": "1.1.3", 14 | "elm/parser": "1.1.0", 15 | "elm/svg": "1.0.1", 16 | "mdgriffith/elm-ui": "1.1.5", 17 | "ohanhi/keyboard": "2.0.0" 18 | }, 19 | "indirect": { 20 | "elm/time": "1.0.0", 21 | "elm/url": "1.0.0", 22 | "elm/virtual-dom": "1.0.2" 23 | } 24 | }, 25 | "test-dependencies": { 26 | "direct": { 27 | "elm-explorations/test": "1.0.0" 28 | }, 29 | "indirect": { 30 | "elm/random": "1.0.0" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /elmapp.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | homepage: "https://joshuaji.com/derivative/", 3 | }; 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "derivative", 3 | "version": "1.0.0", 4 | "description": "Symbolic Differentiation with Elm", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "start": "elm-app start", 11 | "build": "elm-app build" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/joshuanianji/Derivative.git" 16 | }, 17 | "author": "", 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/joshuanianji/Derivative/issues" 21 | }, 22 | "homepage": "https://github.com/joshuanianji/Derivative#readme", 23 | "devDependencies": { 24 | "create-elm-app": "^5.22.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/public/favicon.ico -------------------------------------------------------------------------------- /public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/public/icon.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Derivative Calculator 7 | 8 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 14 | 15 | 22 | 23 | 26 | 27 | 30 | 31 | 34 | 35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Elm App", 3 | "name": "Create Elm App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "icon.png", 12 | "sizes": "256x256", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "theme_color": "#000000", 19 | "background_color": "#ffffff" 20 | } -------------------------------------------------------------------------------- /src/GithubLogo.elm: -------------------------------------------------------------------------------- 1 | module GithubLogo exposing (view) 2 | 3 | import Element exposing (Element) 4 | import Html 5 | import Html.Attributes 6 | import Svg 7 | import Svg.Attributes 8 | 9 | 10 | view : Element msg 11 | view = 12 | Html.a 13 | [ Html.Attributes.href "https://github.com/joshuanianji/Derivative" 14 | , Html.Attributes.class "github-corner" 15 | ] 16 | [ Svg.svg 17 | [ Svg.Attributes.width "80" 18 | , Svg.Attributes.height "80" 19 | , Svg.Attributes.viewBox "0 0 250 250" 20 | , Svg.Attributes.fill "#151513" 21 | , Svg.Attributes.color "#fff" 22 | ] 23 | [ Svg.path 24 | [ Svg.Attributes.d "M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" ] 25 | [] 26 | , Svg.path 27 | [ Svg.Attributes.d "M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" 28 | , Svg.Attributes.fill "#fff" 29 | , Svg.Attributes.style "transform-origin: 130px 106px;" 30 | , Svg.Attributes.class "octo-arm" 31 | ] 32 | [] 33 | , Svg.path 34 | [ Svg.Attributes.d "M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" 35 | , Svg.Attributes.fill "#fff" 36 | , Svg.Attributes.class "octo-body" 37 | ] 38 | [] 39 | ] 40 | ] 41 | |> Element.html 42 | -------------------------------------------------------------------------------- /src/Main.elm: -------------------------------------------------------------------------------- 1 | module Main exposing (main) 2 | 3 | import Browser 4 | import Dict exposing (Dict) 5 | import Element exposing (Element, centerX, centerY, fill, height, padding, px, spacing, text, width) 6 | import Element.Background as Background 7 | import Element.Border as Border 8 | import Element.Events as Events 9 | import Element.Font as Font 10 | import Element.Input as Input 11 | import GithubLogo 12 | import Html exposing (Html) 13 | import Html.Attributes 14 | import Json.Encode 15 | import Keyboard exposing (Key(..)) 16 | import Math exposing (Expr(..), MathError(..)) 17 | import Ports 18 | 19 | 20 | main : Program () Model Msg 21 | main = 22 | Browser.element 23 | { init = init 24 | , view = view 25 | , update = update 26 | , subscriptions = subscriptions 27 | } 28 | 29 | 30 | 31 | -- MODEL 32 | 33 | 34 | type alias Model = 35 | { latexStr : String 36 | , expr : Result MathError Expr 37 | , derivative : Result MathError Expr 38 | , debug : Bool 39 | , tutorial : Bool 40 | , pressedKeys : List Key 41 | , blocks : Dict String Bool 42 | } 43 | 44 | 45 | init : () -> ( Model, Cmd Msg ) 46 | init _ = 47 | ( { latexStr = "" 48 | , expr = Math.initExpr 49 | , derivative = Math.initExpr 50 | , debug = False 51 | , tutorial = False 52 | , pressedKeys = [] 53 | , blocks = 54 | Dict.fromList 55 | [ ( "Credits", False ) 56 | , ( "Overview", True ) 57 | , ( "Supported Features", False ) 58 | , ( "Caveats", False ) 59 | , ( "Keyboard Shortcuts", False ) 60 | ] 61 | } 62 | , Cmd.none 63 | ) 64 | 65 | 66 | 67 | -- VIEW 68 | 69 | 70 | view : Model -> Html Msg 71 | view model = 72 | Element.column 73 | [ width fill 74 | , height fill 75 | , Element.paddingXY 50 70 76 | , Element.spacing 32 77 | ] 78 | [ -- header 79 | Element.paragraph 80 | [ Font.size 32 81 | , Font.center 82 | ] 83 | [ text "Symbolic Differentiation Calculator" ] 84 | 85 | -- main content 86 | , if model.tutorial then 87 | tutorial model 88 | 89 | else 90 | derivativeView model 91 | 92 | -- footer 93 | , Element.paragraph 94 | [ width fill 95 | , Font.center 96 | ] 97 | [ text "All source code is available on " 98 | , link "Github" "https://github.com/joshuanianji/Derivative" 99 | , text "!" 100 | ] 101 | ] 102 | -- surrounds with borders 103 | |> (\el -> 104 | Element.row 105 | [ width fill, height fill ] 106 | [ Element.el [ width <| Element.fillPortion 1, height fill ] Element.none 107 | , Element.el [ width <| Element.fillPortion 4, height fill ] el 108 | , Element.el [ width <| Element.fillPortion 1, height fill ] Element.none 109 | ] 110 | ) 111 | |> Element.layout 112 | [ Font.family 113 | [ Font.typeface "Computer Modern" ] 114 | , Element.inFront <| 115 | Element.el 116 | [ Element.alignTop 117 | , Element.alignRight 118 | ] 119 | GithubLogo.view 120 | ] 121 | 122 | 123 | 124 | -- Tutorial 125 | 126 | 127 | tutorial : Model -> Element Msg 128 | tutorial model = 129 | Element.column 130 | [ Element.spacing 32 131 | , width fill 132 | , height fill 133 | ] 134 | [ -- i NEED to make the Info & Help Guide a paragraph, not an Element.el or else it'll shift it one pixel up lol. 135 | Element.paragraph [ Font.center ] [ text "Info & Help Guide" ] 136 | , Element.el [ centerX ] <| tutorialToggle model 137 | , block model 138 | { title = ( 1, "Overview" ) 139 | , body = overview 140 | , toggleMsg = ToggleBlock "Overview" 141 | , get = Dict.get "Overview" 142 | } 143 | , block model 144 | { title = ( 2, "Supported Features" ) 145 | , body = supportedFeatures 146 | , toggleMsg = ToggleBlock "Supported Features" 147 | , get = Dict.get "Supported Features" 148 | } 149 | , block model 150 | { title = ( 3, "Caveats" ) 151 | , body = caveats 152 | , toggleMsg = ToggleBlock "Caveats" 153 | , get = Dict.get "Caveats" 154 | } 155 | , block model 156 | { title = ( 4, "Keyboard Shortcuts" ) 157 | , body = keyboardShortcuts 158 | , toggleMsg = ToggleBlock "Keyboard Shortcuts" 159 | , get = Dict.get "Keyboard Shortcuts" 160 | } 161 | ] 162 | 163 | 164 | overview : Element Msg 165 | overview = 166 | Element.paragraph 167 | [ spacing 4 ] 168 | [ text "Welcome to my Derivative Calculator! " 169 | , text "This project, inspired by " 170 | , link "this Haskell blog post" "http://5outh.blogspot.com/2013/05/symbolic-calculus-in-haskell.html" 171 | , text ", aims to provide symbolic differentiation with user friendly input and output. Read further to see supported features and caveats, or exit this help guide and get started!" 172 | ] 173 | 174 | 175 | supportedFeatures : Element Msg 176 | supportedFeatures = 177 | let 178 | supportedFeaturesTable = 179 | [ { feature = "Four Basic Operations" 180 | , display = "+ - \\cdot \\frac{a}{b}" 181 | , typed = "+ - * a/b" 182 | } 183 | , { feature = "Exponents" 184 | , display = "a^b" 185 | , typed = "a^b" 186 | } 187 | , { feature = "Six Major Trigonometric Functions" 188 | , display = "sinx \\cdot \\tan (3 \\cdot \\pi x)" 189 | , typed = "sinx * tan(3 * pi x)" 190 | } 191 | , { feature = "Square Root" 192 | , display = "\\sqrt{}" 193 | , typed = "sqrt" 194 | } 195 | , { feature = "Logarithm" 196 | , display = "\\ln" 197 | , typed = "ln" 198 | } 199 | , { feature = "Variables" 200 | , display = "a \\cdot a_b \\cdot a_{pple}" 201 | , typed = "a * a_b * a_pple" 202 | } 203 | ] 204 | 205 | header str = 206 | Element.paragraph 207 | [ Font.bold 208 | , Font.size 26 209 | ] 210 | [ Element.text str ] 211 | 212 | viewInTable elem = 213 | Element.paragraph [ centerY ] [ elem ] 214 | in 215 | Element.textColumn 216 | [ spacing 16 217 | , width fill 218 | ] 219 | [ Element.paragraph 220 | [ spacing 4 ] 221 | [ text "I used the " 222 | , link "MathQuill" "http://mathquill.com/" 223 | , text " library, the same one " 224 | , link "Desmos" "http://desmos.com" 225 | , text " uses for its calculator. Because of this, the latex input is pretty intuitive!" 226 | ] 227 | , Element.paragraph 228 | [ spacing 4 ] 229 | [ text "As of right now, this program does not support multivariable calculus or implicit differentiation, though because I treat variables like constants, one can make an argument for partial derivatives." 230 | ] 231 | , Element.paragraph 232 | [ spacing 4 ] 233 | [ text "For a full list of supported functions, refer to the table below." 234 | ] 235 | 236 | -- make a table 237 | , Element.table 238 | [ spacing 16 239 | , Element.paddingXY 0 16 240 | ] 241 | { data = supportedFeaturesTable 242 | , columns = 243 | [ { header = header "Function" 244 | , width = fill 245 | , view = 246 | \f -> viewInTable <| Element.text f.feature 247 | } 248 | , { header = header "Display" 249 | , width = fill 250 | , view = 251 | \f -> viewInTable <| staticMath 20 f.display 252 | } 253 | , { header = header "What to Type" 254 | , width = fill 255 | , view = 256 | \f -> viewInTable <| typed f.typed 257 | } 258 | ] 259 | } 260 | ] 261 | 262 | 263 | caveats : Element Msg 264 | caveats = 265 | let 266 | -- for padding 267 | edges = 268 | { top = 0 269 | , right = 0 270 | , bottom = 0 271 | , left = 0 272 | } 273 | 274 | subHeading str = 275 | Element.paragraph 276 | [ Font.size 24 277 | , Element.paddingEach { edges | top = 16 } 278 | , Font.bold 279 | ] 280 | [ text str ] 281 | in 282 | Element.textColumn 283 | [ spacing 16 284 | , width fill 285 | ] 286 | [ Element.paragraph 287 | [ spacing 4 ] 288 | [ text "As cool as this project and its supporting libraries are, there are some limitations and restrictions." ] 289 | , subHeading "Trigonometric Functions" 290 | , Element.paragraph 291 | [ spacing 4 ] 292 | [ text "It is common to write exponentials for trigonometric functions like " 293 | , staticMath 18 "sin^3 x" 294 | , text ", but my parser is too stupid to understand that kind of expression! To write exponentials of trigonometric functions, and any unary function, it is highly advised to use parentheses, like " 295 | , staticMath 18 "(sin x)^3" 296 | , text ". (Rip latex formatting)" 297 | ] 298 | , subHeading "Simplification" 299 | , Element.paragraph 300 | [ spacing 4 ] 301 | [ text "TL;DR: my simplification algorithm sucks." ] 302 | , Element.paragraph 303 | [ spacing 4 ] 304 | [ text " Looking at my source code, the function for simplifying an expression takes the crown for the longest function definition - by a long shot. It's a good thing the Elm compiler does a good job at pointing out redundant case statements to me. " 305 | , text "Still, simplification is difficult and feels wonky due to the nature of my data type being a tree structure. (If you want to take a look at what the data type is for a certain expression, open the debug tool). " 306 | , text "An easy example is calculating the derivative of " 307 | , staticMath 18 "(x+1)(x-4)" 308 | , text ", which trivially turns out to " 309 | , staticMath 18 "2x-3," 310 | , text ", yet my algorithm, using the product rule, stops at " 311 | , staticMath 18 "x-4+x+1." 312 | ] 313 | , Element.paragraph 314 | [ spacing 4 ] 315 | [ text "Looking at the debug tool, one notices that the variables and constants that could be joined together are in different branches of the data type. " 316 | , text "I have no doubt that there is a way to combine these together using a clever algorithm, but I'm not educated enough to fix this haha. Maybe I'll learn it one day." 317 | ] 318 | , subHeading "Miscellaneous" 319 | , Element.paragraph 320 | [ spacing 4 ] 321 | [ text "This one bug drives me nuts and it's the fact that my parser parses " 322 | , staticMath 18 "sin 3" 323 | , text " and any unary function where it's followed immediately by a constant as a variable multiplied by a constant! It would read the input as " 324 | , text "(Mult (Var \"\\sin\") (Const 3)), " 325 | , text "like what the heck?? And replacing the constant with a variable is fine. I have honestly no idea how to fix this but to be honest I won't waste energy on it, as it fixes itself with parentheses and this bug won't affect the end user too much...I think." 326 | ] 327 | , subHeading "More bugs?" 328 | , Element.paragraph 329 | [ spacing 4 ] 330 | [ text "If you find anything out of the ordinary, open a new issue on " 331 | , link "The Github Repository" "https://github.com/joshuanianji/Derivative" 332 | , text " or open a pull request! I am open to suggestions on my code or anything else about this project." 333 | ] 334 | ] 335 | 336 | 337 | keyboardShortcuts : Element Msg 338 | keyboardShortcuts = 339 | let 340 | shortcutsTable = 341 | [ { toggle = "Calculate Derivative" 342 | , typed = "ENTER" 343 | } 344 | , { toggle = "Clear" 345 | , typed = "SHIFT + C" 346 | } 347 | , { toggle = "Toggle Debug" 348 | , typed = "SHIFT + D" 349 | } 350 | , { toggle = "Toggle Tutorial" 351 | , typed = "SHIFT + T" 352 | } 353 | ] 354 | 355 | header str = 356 | Element.paragraph 357 | [ Font.bold 358 | , Font.size 26 359 | ] 360 | [ Element.text str ] 361 | 362 | viewInTable elem = 363 | Element.paragraph [ centerY ] [ elem ] 364 | in 365 | Element.table 366 | [ spacing 16 367 | , Element.paddingXY 0 16 368 | ] 369 | { data = shortcutsTable 370 | , columns = 371 | [ { header = header "Function" 372 | , width = fill 373 | , view = 374 | \f -> viewInTable <| Element.text f.toggle 375 | } 376 | , { header = header "Keyboard" 377 | , width = fill 378 | , view = 379 | \f -> viewInTable <| typed f.typed 380 | } 381 | ] 382 | } 383 | 384 | 385 | tutorialToggle : Model -> Element Msg 386 | tutorialToggle model = 387 | Element.el 388 | [ Border.width 1 389 | , Border.rounded 21 390 | , Border.color <| Element.rgb 0 0 0 391 | , height <| px 42 392 | , width <| px 42 393 | , Element.pointer 394 | , Events.onClick ToggleTutorial 395 | ] 396 | <| 397 | Element.el 398 | [ centerX 399 | , centerY 400 | , unselectable 401 | ] 402 | <| 403 | if model.tutorial then 404 | text "╳" 405 | 406 | else 407 | text "?" 408 | 409 | 410 | 411 | -- Derivative 412 | 413 | 414 | derivativeView : Model -> Element Msg 415 | derivativeView model = 416 | Element.column 417 | [ Element.spacing 32 418 | , width fill 419 | , height fill 420 | ] 421 | [ Element.paragraph 422 | [ width fill 423 | , Font.center 424 | ] 425 | [ text "Created by " 426 | , link "Joshua Ji" "https://github.com/joshuanianji/Derivative" 427 | ] 428 | , Element.el [ centerX ] <| tutorialToggle model 429 | , heading ( 1, "Function Input" ) 430 | , Element.column 431 | [ width fill, spacing 8 ] 432 | [ input model 433 | , if model.debug then 434 | latexToExpr model.expr 435 | 436 | else 437 | Element.none 438 | ] 439 | , heading ( 2, "Derivative" ) 440 | , Element.column 441 | [ width fill, spacing 8 ] 442 | [ derivative model 443 | , if model.debug then 444 | latexToExpr model.derivative 445 | 446 | else 447 | Element.none 448 | ] 449 | , block model 450 | { title = ( 3, "Credits" ) 451 | , body = credits 452 | , toggleMsg = ToggleBlock "Credits" 453 | , get = Dict.get "Credits" 454 | } 455 | , Element.el [ centerX ] <| debugModeToggle model 456 | ] 457 | 458 | 459 | debugModeToggle : Model -> Element Msg 460 | debugModeToggle model = 461 | Input.checkbox 462 | [] 463 | { onChange = ToggleDebug 464 | , icon = 465 | \debugOn -> 466 | Element.el 467 | [ Font.bold 468 | , unselectable 469 | ] 470 | <| 471 | if debugOn then 472 | text "On" 473 | 474 | else 475 | text "Off" 476 | , checked = model.debug 477 | , label = 478 | Input.labelLeft 479 | [ unselectable ] 480 | (text "Debug mode:") 481 | } 482 | 483 | 484 | input : Model -> Element Msg 485 | input model = 486 | Element.column 487 | [ spacing 32 488 | , centerX 489 | ] 490 | [ Element.el [ Element.spacing 16, centerX ] <| functionInput model 491 | , Element.row 492 | [ spacing 32 493 | , centerX 494 | ] 495 | [ Input.button 496 | [ Border.width 1 497 | , Border.rounded 5 498 | , Border.color <| Element.rgb 0 0 0 499 | , Element.padding 12 500 | ] 501 | { onPress = Just Clear 502 | , label = text "Clear" 503 | } 504 | , Input.button 505 | [ Border.width 1 506 | , Border.rounded 5 507 | , Border.color <| Element.rgb 0 0 0 508 | , Element.padding 12 509 | ] 510 | { onPress = Just Calculate 511 | , label = text "Calculate" 512 | } 513 | ] 514 | ] 515 | 516 | 517 | latexToExpr : Result MathError Expr -> Element Msg 518 | latexToExpr resultExpr = 519 | Element.column 520 | [ centerX ] 521 | [ Element.paragraph 522 | [ Font.size 32 523 | , Font.center 524 | , spacing 16 525 | , Element.padding 16 526 | ] 527 | [ text "Latex → Expr" ] 528 | , case resultExpr of 529 | Ok expr -> 530 | Element.paragraph 531 | [ Font.center ] 532 | [ text <| Math.toString expr ] 533 | 534 | Err error -> 535 | Math.errorToString error 536 | |> text 537 | |> List.singleton 538 | |> Element.paragraph 539 | [ Font.center 540 | , Element.spacing 16 541 | ] 542 | ] 543 | 544 | 545 | derivative : Model -> Element Msg 546 | derivative model = 547 | (case model.derivative of 548 | Ok der -> 549 | Math.asLatex der 550 | |> (\s -> "\\frac{df}{dx}=" ++ s) 551 | |> staticMath 20 552 | 553 | Err mathError -> 554 | Math.errorToString mathError 555 | |> text 556 | |> List.singleton 557 | |> Element.paragraph [ Font.center ] 558 | ) 559 | |> Element.el 560 | [ Font.center 561 | , Element.scrollbarX 562 | , width fill 563 | ] 564 | |> Element.el 565 | [ spacing 16 566 | , Element.padding 16 567 | , width fill 568 | ] 569 | 570 | 571 | credits : Element Msg 572 | credits = 573 | Element.column 574 | [ spacing 16 575 | , width fill 576 | ] 577 | [ text "Special thanks to:" 578 | , Element.paragraph [] [ text "Benjamin Kovach, for writing ", link "Symbolic Calculus in Haskell" "http://5outh.blogspot.com/2013/05/symbolic-calculus-in-haskell.html", text ", the blog post which inspired this project." ] 579 | , Element.paragraph [] [ link "MathQuill" "http://mathquill.com/", text ", for making it so easy manage LaTeX input and output." ] 580 | , Element.paragraph [] [ link "Create Elm App" "https://github.com/halfzebra/create-elm-app", text " with which this project is bootstrapped." ] 581 | , Element.paragraph [] [ link "Dmy" "https://github.com/dmy", text ", for creating ", link "Elm Pratt Parser" "https://github.com/dmy/elm-pratt-parser", text ", an awesome library which implements the theoretical parser of the same name in Elm." ] 582 | , Element.paragraph [] [ link "The Elm Language" "https://elm-lang.org/", text " for being so easy to work with." ] 583 | ] 584 | 585 | 586 | 587 | -- HELPER FUNCTIONS 588 | 589 | 590 | type alias BlockData = 591 | { title : ( Int, String ) 592 | , body : Element Msg 593 | , toggleMsg : Msg 594 | , get : Dict String Bool -> Maybe Bool 595 | } 596 | 597 | 598 | block : Model -> BlockData -> Element Msg 599 | block model blockData = 600 | let 601 | isOpen = 602 | Maybe.withDefault False (blockData.get model.blocks) 603 | in 604 | Element.column 605 | [ spacing 8 606 | , width fill 607 | ] 608 | [ heading blockData.title 609 | |> Element.el 610 | [ if isOpen then 611 | -- black font 612 | Font.color <| Element.rgb 0 0 0 613 | 614 | else 615 | -- gray font 616 | Font.color <| Element.rgb255 169 169 169 617 | , Element.pointer 618 | , Events.onClick blockData.toggleMsg 619 | , unselectable 620 | ] 621 | , if isOpen then 622 | blockData.body 623 | |> Element.el 624 | [ Element.paddingXY 46 0 625 | , width fill 626 | ] 627 | 628 | else 629 | Element.none 630 | ] 631 | 632 | 633 | heading : ( Int, String ) -> Element Msg 634 | heading ( num, title ) = 635 | Element.row 636 | [ width fill 637 | , Font.bold 638 | , Font.size 30 639 | , Element.paddingXY 0 24 640 | ] 641 | [ String.fromInt num 642 | |> text 643 | |> List.singleton 644 | |> Element.paragraph [ width (px 30) ] 645 | , Element.paragraph [ Element.paddingXY 16 0 ] 646 | [ text <| title ] 647 | ] 648 | 649 | 650 | link : String -> String -> Element Msg 651 | link linkName url = 652 | Element.newTabLink 653 | [ width Element.shrink 654 | , Font.color <| Element.rgb255 0 63 135 655 | 656 | -- , Font.underline 657 | ] 658 | { url = url 659 | , label = text linkName 660 | } 661 | 662 | 663 | 664 | -- represents a keyboard character 665 | 666 | 667 | typed : String -> Element Msg 668 | typed char = 669 | Element.el 670 | [ Font.family 671 | [ Font.typeface "Courier New" 672 | , Font.monospace 673 | ] 674 | , Border.color <| Element.rgb 0 0 0 675 | , Border.width 1 676 | , Border.rounded 3 677 | , Background.color <| Element.rgb255 220 220 220 678 | , Element.paddingXY 4 2 679 | , Font.size 20 680 | ] 681 | <| 682 | Element.text char 683 | 684 | 685 | unselectable : Element.Attribute Msg 686 | unselectable = 687 | Element.htmlAttribute (Html.Attributes.style "user-select" "none") 688 | 689 | 690 | 691 | -- web component stuff 692 | 693 | 694 | functionInput : Model -> Element Msg 695 | functionInput _ = 696 | Html.div [] 697 | [ Html.node "mathquill-static" 698 | [ Html.Attributes.property "latexValue" <| 699 | Json.Encode.string "f(x)=" 700 | ] 701 | [] 702 | , Html.span 703 | [ Html.Attributes.style "display" "inline-block" 704 | , Html.Attributes.style "height" "shrink" 705 | , Html.Attributes.style "width" "shrink" 706 | ] 707 | [ Html.node "mathquill-input" [] [] ] 708 | ] 709 | |> Element.html 710 | |> Element.el [ Element.scrollbarX ] 711 | 712 | 713 | staticMath : Int -> String -> Element Msg 714 | staticMath fontSize latexStr = 715 | Html.node "mathquill-static" 716 | [ Html.Attributes.property "latexValue" <| 717 | Json.Encode.string latexStr 718 | , Html.Attributes.property "style" 719 | (Json.Encode.string <| ("font-size: " ++ String.fromInt fontSize ++ "px; vertical-align: text-bottom")) 720 | ] 721 | [] 722 | |> Element.html 723 | 724 | 725 | 726 | -- UPDATE 727 | 728 | 729 | type Msg 730 | = ToggleDebug Bool 731 | | ToggleTutorial 732 | | ToggleBlock String -- because I use a string dictionary lel 733 | | ChangedLatexStr String 734 | | Calculate 735 | | Clear 736 | | KeyMsg Keyboard.Msg 737 | 738 | 739 | update : Msg -> Model -> ( Model, Cmd Msg ) 740 | update msg model = 741 | case msg of 742 | ToggleDebug currentDebugMode -> 743 | ( { model | debug = currentDebugMode }, Cmd.none ) 744 | 745 | ToggleTutorial -> 746 | ( { model | tutorial = not model.tutorial }, Cmd.none ) 747 | 748 | ToggleBlock blockSelect -> 749 | let 750 | blocks = 751 | model.blocks 752 | 753 | newBlocks = 754 | Dict.update 755 | blockSelect 756 | (Maybe.map not) 757 | blocks 758 | in 759 | ( { model | blocks = newBlocks }, Cmd.none ) 760 | 761 | ChangedLatexStr latexStr -> 762 | ( { model 763 | | latexStr = latexStr 764 | , expr = Math.fromLatex latexStr 765 | } 766 | , Cmd.none 767 | ) 768 | 769 | Calculate -> 770 | ( { model | derivative = Math.derivative model.expr } 771 | , Cmd.none 772 | ) 773 | 774 | Clear -> 775 | ( { model 776 | | latexStr = "" 777 | , expr = Math.initExpr 778 | , derivative = Math.initExpr 779 | } 780 | , Ports.clear () 781 | ) 782 | 783 | KeyMsg keyMsg -> 784 | let 785 | newKeys = 786 | Keyboard.update keyMsg model.pressedKeys 787 | 788 | -- possible shortcuts in order of precedence. If multiple are valid we enact the first one 789 | possibleShortcuts = 790 | [ ( [ Keyboard.Enter ], Calculate ) --calculate derivative 791 | , ( [ Keyboard.Shift, Keyboard.Character "C" ], Clear ) -- clear 792 | , ( [ Keyboard.Shift, Keyboard.Character "D" ], ToggleDebug (not model.debug) ) -- debug 793 | , ( [ Keyboard.Shift, Keyboard.Character "T" ], ToggleTutorial ) -- tutorial 794 | ] 795 | 796 | shortcuts = 797 | List.filterMap 798 | (\( keys, message ) -> 799 | -- if all the keys are currently being held down 800 | if List.all (\k -> List.member k newKeys) keys then 801 | Just message 802 | 803 | else 804 | Nothing 805 | ) 806 | possibleShortcuts 807 | 808 | newModel = 809 | { model | pressedKeys = newKeys } 810 | in 811 | case shortcuts of 812 | message :: _ -> 813 | update message newModel 814 | 815 | [] -> 816 | ( newModel, Cmd.none ) 817 | 818 | 819 | 820 | -- SUBSCRIPTIONS 821 | 822 | 823 | subscriptions : Model -> Sub Msg 824 | subscriptions _ = 825 | Sub.batch 826 | [ Ports.changedLatex ChangedLatexStr 827 | , Sub.map KeyMsg Keyboard.subscriptions 828 | ] 829 | -------------------------------------------------------------------------------- /src/Math.elm: -------------------------------------------------------------------------------- 1 | module Math exposing 2 | ( Expr(..) 3 | , MathError(..) 4 | , asLatex 5 | , derivative 6 | , errorToString 7 | , fromLatex 8 | , fullSimplify 9 | , initExpr 10 | , toString 11 | ) 12 | 13 | {- Module for parsing and dealing with the Math stuff 14 | Many thanks to http://5outh.blogspot.com/2013/05/symbolic-calculus-in-haskell.html 15 | And the Pratt Parser for existing, you've made my life so much easier 16 | -} 17 | 18 | import Parser.Advanced as Parser exposing ((|.), (|=), Parser, Token(..)) 19 | import Pratt.Advanced as Pratt 20 | import Result 21 | import Set 22 | 23 | 24 | 25 | ---------------------------------- 26 | -- TYPES 27 | ---------------------------------- 28 | 29 | 30 | type 31 | Expr 32 | -- Trivial functions 33 | = Const Float 34 | | Var String 35 | | Add Expr Expr 36 | | Sub Expr Expr 37 | | Div Expr Expr 38 | | Mult Expr Expr 39 | | Pow Expr Expr 40 | -- Trig 41 | | Sin Expr 42 | | Csc Expr 43 | | Cos Expr 44 | | Sec Expr 45 | | Tan Expr 46 | | Cot Expr 47 | -- other 48 | | Ln Expr 49 | | Sqrt Expr 50 | | Negative Expr 51 | 52 | 53 | {-| Not ready yet - I need the absolute value funcion for the derivative of Arccsc and I don't want to do that yet lol. 54 | -- Inverse trig 55 | | Arcsin Expr 56 | | Arccsc Expr 57 | | Arccos Expr 58 | | Arcsec Expr 59 | | Arctan Expr 60 | | Arccot Expr 61 | -- Hyperbolic 62 | | Sinh Expr 63 | | Csch Expr 64 | | Cosh Expr 65 | | Sech Expr 66 | | Tanh Expr 67 | | Coth Expr 68 | -} 69 | type MathError 70 | = DivisionByZero 71 | | ExtraVariable String 72 | | ParserErrors (List String) 73 | | DerivativeError String 74 | 75 | 76 | 77 | ------------------------------------ 78 | -- HELPERS 79 | ------------------------------------ 80 | 81 | 82 | negate : Expr -> Expr 83 | negate = 84 | Negative 85 | 86 | 87 | toString : Expr -> String 88 | toString expr = 89 | case expr of 90 | Const a -> 91 | "(Const " ++ String.fromFloat a ++ ")" 92 | 93 | Var str -> 94 | "(Var \"" ++ str ++ "\")" 95 | 96 | Add a b -> 97 | "(Add " ++ toString a ++ " " ++ toString b ++ ")" 98 | 99 | Sub a b -> 100 | "(Sub " ++ toString a ++ " " ++ toString b ++ ")" 101 | 102 | Mult a b -> 103 | "(Mult " ++ toString a ++ " " ++ toString b ++ ")" 104 | 105 | Div a b -> 106 | "(Div " ++ toString a ++ " " ++ toString b ++ ")" 107 | 108 | Pow a b -> 109 | "(Pow " ++ toString a ++ " " ++ toString b ++ ")" 110 | 111 | Sin a -> 112 | "(Sin " ++ toString a ++ ")" 113 | 114 | Csc a -> 115 | "(Csc " ++ toString a ++ ")" 116 | 117 | Cos a -> 118 | "(Cos " ++ toString a ++ ")" 119 | 120 | Sec a -> 121 | "(Sec " ++ toString a ++ ")" 122 | 123 | Tan a -> 124 | "(Tan " ++ toString a ++ ")" 125 | 126 | Cot a -> 127 | "(Cot " ++ toString a ++ ")" 128 | 129 | Ln a -> 130 | "(Ln " ++ toString a ++ ")" 131 | 132 | Sqrt f -> 133 | "(Sqrt " ++ toString f ++ ")" 134 | 135 | Negative f -> 136 | "(Negative " ++ toString f ++ ")" 137 | 138 | 139 | 140 | -- DERIVATIVE 141 | 142 | 143 | derivative : Result MathError Expr -> Result MathError Expr 144 | derivative = 145 | fullSimplify 146 | >> Result.map derivativeIter 147 | >> fullSimplify 148 | 149 | 150 | derivativeIter : Expr -> Expr 151 | derivativeIter expr = 152 | case expr of 153 | Const _ -> 154 | Const 0 155 | 156 | Var "x" -> 157 | Const 1 158 | 159 | Var _ -> 160 | Const 0 161 | 162 | Add a b -> 163 | Add (derivativeIter a) (derivativeIter b) 164 | 165 | Sub a b -> 166 | Sub (derivativeIter a) (derivativeIter b) 167 | 168 | Mult a b -> 169 | Add (Mult (derivativeIter a) b) (Mult a (derivativeIter b)) 170 | 171 | Div a b -> 172 | Div 173 | (Sub (Mult (derivativeIter a) b) (Mult a (derivativeIter b))) 174 | (Mult b b) 175 | 176 | Pow (Var "x") (Const b) -> 177 | Mult (Const b) (Pow (Var "x") (Const (b - 1))) 178 | 179 | Pow (Var "x") (Var a) -> 180 | case a of 181 | "x" -> 182 | Mult 183 | (Pow (Var "x") (Var "x")) 184 | (Add (Ln (Var "x")) (Const 1)) 185 | 186 | _ -> 187 | Mult (Var a) (Pow (Var "x") (Sub (Var a) (Const 1))) 188 | 189 | Pow (Var "e") f -> 190 | Mult (derivativeIter f) (Pow (Var "e") f) 191 | 192 | -- (d/dx) f(x)^n = f'(x) * n * f(x) ^ (n-1) 193 | Pow a (Const n) -> 194 | Mult (derivativeIter a) (Mult (Const n) (Pow a (Const <| n - 1))) 195 | 196 | -- LOL I JUST USED THIS (https://mathvault.ca/exponent-rule-derivative/#Example_1_pix) 197 | Pow f g -> 198 | Mult 199 | (Pow f g) 200 | (Add 201 | (Mult (derivativeIter g) (Ln f)) 202 | (Mult (derivativeIter f) (Div g f)) 203 | ) 204 | 205 | -- Trig - a lot of chain rules are used 206 | Sin f -> 207 | Mult (derivativeIter f) (Cos f) 208 | 209 | Csc f -> 210 | Mult (Csc f) (Cot f) 211 | |> Mult (derivativeIter f) 212 | |> negate 213 | 214 | Cos f -> 215 | Sin f 216 | |> Mult (derivativeIter f) 217 | |> negate 218 | 219 | Sec f -> 220 | Mult (Sec f) (Tan f) 221 | |> Mult (derivativeIter f) 222 | 223 | Tan f -> 224 | Mult (Sec f) (Sec f) 225 | |> Mult (derivativeIter f) 226 | 227 | Cot f -> 228 | Mult (Csc f) (Csc f) 229 | |> Mult (derivativeIter f) 230 | 231 | -- Logarithm 232 | Ln f -> 233 | Div (derivativeIter f) f 234 | 235 | -- Square Root 236 | Sqrt f -> 237 | Mult 238 | (derivativeIter f) 239 | (Mult (Div (Const 1) (Const 2)) (Pow f (negate <| Div (Const 1) (Const 2)))) 240 | 241 | Negative a -> 242 | Mult (Const -1) (derivativeIter a) 243 | 244 | 245 | 246 | -- SIMPLIFY 247 | 248 | 249 | fullSimplify : Result MathError Expr -> Result MathError Expr 250 | fullSimplify expr = 251 | let 252 | fullSimplifyIter cur last = 253 | if cur == last then 254 | cur 255 | 256 | else 257 | let 258 | curNext = 259 | Result.andThen simplify cur 260 | in 261 | fullSimplifyIter curNext cur 262 | in 263 | fullSimplifyIter expr (Ok <| Const 0) 264 | 265 | 266 | {-| Simplify functions based on cases 267 | 268 | bruh this code is loNGGGG because there are so many cases where we can simplify the expression by rip. 269 | Also its starting to look like lisp lol 270 | 271 | -} 272 | simplify : Expr -> Result MathError Expr 273 | simplify expr1 = 274 | case expr1 of 275 | Const a -> 276 | if a < 0 then 277 | Negative (Const -a) 278 | |> Ok 279 | 280 | else 281 | Ok <| Const a 282 | 283 | -- Addition and Subtraction Identities 284 | Add (Const a) (Const b) -> 285 | Ok <| Const (a + b) 286 | 287 | Add a (Const n) -> 288 | if n == 0 then 289 | simplify a 290 | 291 | else 292 | Result.map2 Add (simplify a) (Ok <| Const n) 293 | 294 | Add (Const n) a -> 295 | if n == 0 then 296 | simplify a 297 | 298 | else 299 | Result.map2 Add (Ok <| Const n) (simplify a) 300 | 301 | -- x + 3x or any other combination will add the x's together 302 | Add (Mult (Var a) (Const n)) (Var b) -> 303 | if a == b then 304 | Ok <| Mult (Var a) (Const (n + 1)) 305 | 306 | else 307 | Ok <| Add (Mult (Var a) (Const n)) (Var b) 308 | 309 | Add (Mult (Const n) (Var a)) (Var b) -> 310 | if a == b then 311 | Ok <| Mult (Var a) (Const (n + 1)) 312 | 313 | else 314 | Ok <| Add (Mult (Const n) (Var a)) (Var b) 315 | 316 | Add (Var b) (Mult (Const n) (Var a)) -> 317 | if a == b then 318 | Ok <| Mult (Const (n + 1)) (Var a) 319 | 320 | else 321 | Ok <| Add (Var b) (Mult (Const n) (Var a)) 322 | 323 | Add (Var b) (Mult (Var a) (Const n)) -> 324 | if a == b then 325 | Ok <| Mult (Var a) (Const (n + 1)) 326 | 327 | else 328 | Ok <| Add (Var b) (Mult (Var a) (Const n)) 329 | 330 | Sub (Const a) (Const b) -> 331 | Ok <| Const (a - b) 332 | 333 | Sub a (Const n) -> 334 | if n == 0 then 335 | simplify a 336 | 337 | else 338 | Result.map2 Sub (simplify a) (Ok <| Const n) 339 | 340 | Sub (Const n) a -> 341 | if n == 0 then 342 | simplify <| negate a 343 | 344 | else 345 | Result.map2 Sub (Ok <| Const n) (simplify a) 346 | 347 | Sub (Var a) (Var b) -> 348 | if a == b then 349 | Ok <| Const 0 350 | 351 | else 352 | Ok <| Sub (Var a) (Var b) 353 | 354 | -- Multiplication 355 | Mult (Negative a) (Negative b) -> 356 | Result.map2 Mult (simplify a) (simplify b) 357 | 358 | Mult (Const a) (Mult (Const b) expr) -> 359 | Result.map2 Mult (Ok <| Const <| a * b) (simplify expr) 360 | 361 | Mult (Const a) (Mult expr (Const b)) -> 362 | Result.map2 Mult (Ok <| Const <| a * b) (simplify expr) 363 | 364 | Mult expr (Mult (Const a) (Const b)) -> 365 | Result.map2 Mult (Ok <| Const <| a * b) (simplify expr) 366 | 367 | Mult (Const a) (Add b c) -> 368 | Result.map2 Add (Result.map (Mult (Const a)) (simplify b)) (Result.map (Mult <| Const a) (simplify c)) 369 | 370 | Mult (Div a b) c -> 371 | Result.map2 Div (Result.map2 Mult (simplify a) (simplify c)) (simplify b) 372 | 373 | Mult (Const a) (Const b) -> 374 | Ok <| Const (a * b) 375 | 376 | Mult a (Const n) -> 377 | if n == 1 then 378 | simplify a 379 | 380 | else if n == 0 then 381 | Ok <| Const 0 382 | 383 | else 384 | Result.map2 Mult (simplify a) (Ok <| Const n) 385 | 386 | Mult (Const n) a -> 387 | if n == 1 then 388 | simplify a 389 | 390 | else if n == -1 then 391 | Result.map Negative <| simplify a 392 | 393 | else if n == 0 then 394 | Ok <| Const 0 395 | 396 | else 397 | Result.map2 Mult (Ok <| Const n) (simplify a) 398 | 399 | --flipping division stuff - putting it before identities so it is guaranteed to fun 400 | Div (Div a b) c -> 401 | simplify <| Div a (Mult b c) 402 | 403 | Div a (Div b c) -> 404 | simplify <| Div (Mult a c) b 405 | 406 | -- Division Identities 407 | Div (Const a) (Const b) -> 408 | if b == 0 then 409 | Err DivisionByZero 410 | 411 | else if a == 0 then 412 | Ok <| Const 0 413 | 414 | else if a == b then 415 | Ok <| Const 1 416 | 417 | else 418 | Ok <| Div (Const a) (Const b) 419 | 420 | Div a (Const n) -> 421 | if n == 1 then 422 | simplify a 423 | 424 | else 425 | Result.map2 Div (simplify a) (Ok <| Const n) 426 | 427 | Div (Const n) a -> 428 | if n == 0 then 429 | Ok <| Const 0 430 | 431 | else 432 | Result.map2 Div (Ok <| Const n) (simplify a) 433 | 434 | -- removing common denominators (Maybe I should make a gcd function for the Expr type??) 435 | Div (Mult a b) (Mult c d) -> 436 | if a == c then 437 | simplify (Div b d) 438 | 439 | else if b == c then 440 | simplify (Div a d) 441 | 442 | else if a == d then 443 | simplify (Div b c) 444 | 445 | else if b == d then 446 | simplify (Div a c) 447 | 448 | else 449 | Result.map2 Div (simplify <| Mult a b) (simplify <| Mult c d) 450 | 451 | Div (Mult a b) c -> 452 | if c == a then 453 | simplify b 454 | 455 | else if b == c then 456 | simplify a 457 | 458 | else 459 | Result.map2 Div (simplify <| Mult a b) (simplify c) 460 | 461 | Div a (Mult b c) -> 462 | if a == b then 463 | simplify <| Div (Const 1) c 464 | 465 | else if a == c then 466 | simplify <| Div (Const 1) b 467 | 468 | else 469 | Result.map2 Div (simplify a) (simplify <| Mult b c) 470 | 471 | -- Exponential Identities 472 | Pow a (Negative b) -> 473 | Result.map2 Div (Ok <| Const 1) (Ok <| Pow a b) 474 | 475 | Pow (Pow c (Const b)) (Const a) -> 476 | Result.map (Pow c) (Ok <| Const (a * b)) 477 | 478 | Pow (Const a) (Const b) -> 479 | Ok <| Const (a ^ b) 480 | 481 | Pow a (Const n) -> 482 | if n == 1 then 483 | simplify a 484 | 485 | else if n == 0 then 486 | Ok <| Const 1 487 | 488 | else 489 | Result.map2 Pow (simplify a) (Ok <| Const n) 490 | 491 | Pow a (Div (Const b) (Const c)) -> 492 | if b == 1 && c == 2 then 493 | Result.map Sqrt (Ok a) 494 | 495 | else 496 | Result.map2 Pow (Ok a) (Result.map2 Div (Ok <| Const b) (Ok <| Const c)) 497 | 498 | -- Simplify arguments 499 | Add a b -> 500 | if a == b then 501 | Result.map2 Mult (simplify a) (Ok <| Const 2) 502 | 503 | else 504 | Result.map2 Add (simplify a) (simplify b) 505 | 506 | Sub a b -> 507 | if a == b then 508 | Ok <| Const 0 509 | 510 | else 511 | Result.map2 Sub (simplify a) (simplify b) 512 | 513 | Mult a b -> 514 | if a == b then 515 | Result.map2 Pow (simplify a) (Ok <| Const 2) 516 | 517 | else 518 | Result.map2 Mult (simplify a) (simplify b) 519 | 520 | Div a b -> 521 | if a == b then 522 | Ok <| Const 1 523 | 524 | else 525 | Result.map2 Div (simplify a) (simplify b) 526 | 527 | Pow a b -> 528 | Result.map2 Pow (simplify a) (simplify b) 529 | 530 | Sin a -> 531 | Result.map Sin (simplify a) 532 | 533 | Csc a -> 534 | Result.map Csc (simplify a) 535 | 536 | Cos a -> 537 | Result.map Cos (simplify a) 538 | 539 | Sec a -> 540 | Result.map Sec (simplify a) 541 | 542 | Tan a -> 543 | Result.map Tan (simplify a) 544 | 545 | Cot a -> 546 | Result.map Cot (simplify a) 547 | 548 | Ln (Var "e") -> 549 | Ok <| Const 1 550 | 551 | Ln a -> 552 | Result.map Ln (simplify a) 553 | 554 | -- simplifying negatives 555 | Negative (Mult (Const a) b) -> 556 | if a == 1 then 557 | Result.map Negative <| simplify b 558 | 559 | else if a < 0 then 560 | Result.map2 Mult (Ok <| Const -a) (simplify b) 561 | 562 | else 563 | Result.map2 Mult (simplify b) (Ok <| Const a) 564 | |> Result.map Negative 565 | 566 | Negative (Mult a (Const b)) -> 567 | if b == 1 then 568 | Result.map Negative <| simplify a 569 | 570 | else if b < 0 then 571 | Result.map2 Mult (simplify a) (Ok <| Const -b) 572 | 573 | else 574 | Result.map2 Mult (simplify a) (Ok <| Const b) 575 | |> Result.map Negative 576 | 577 | Negative (Negative a) -> 578 | Ok a 579 | 580 | Negative a -> 581 | Result.map Negative <| simplify a 582 | 583 | x -> 584 | Ok <| identity x 585 | 586 | 587 | 588 | ------------------------------------ 589 | -- DISPLAY - displays to latex 590 | ------------------------------------ 591 | 592 | 593 | asLatex : Expr -> String 594 | asLatex expr = 595 | case expr of 596 | Const a -> 597 | String.fromFloat a 598 | 599 | Var str -> 600 | str 601 | 602 | Add a b -> 603 | asLatex a ++ "+" ++ asLatex b 604 | 605 | Sub a b -> 606 | asLatex a ++ "-" ++ asLatex b 607 | 608 | Mult (Const a) (Negative b) -> 609 | "-" ++ String.fromFloat a ++ "\\cdot" ++ asLatex b 610 | 611 | Mult (Const a) b -> 612 | if a == -1 then 613 | "-" ++ asLatex b 614 | -- if we need to write 3(x-2) or something 615 | 616 | else if shouldHaveParentheses (Mult (Const a) b) b then 617 | String.fromFloat a ++ "\\left(" ++ asLatex b ++ "\\right)" 618 | 619 | else 620 | String.fromFloat a ++ asLatex b 621 | 622 | -- Mult (Add a b) (Sub b c) should have parentheses around them. This checks for all cases. 623 | Mult a b -> 624 | case ( shouldHaveParentheses (Mult a b) a, shouldHaveParentheses (Mult a b) b ) of 625 | ( True, True ) -> 626 | "\\left(" ++ asLatex a ++ "\\right)" ++ "\\cdot" ++ "\\left(" ++ asLatex b ++ "\\right)" 627 | 628 | ( True, _ ) -> 629 | "\\left(" ++ asLatex a ++ "\\right)" ++ "\\cdot " ++ asLatex b 630 | 631 | ( _, True ) -> 632 | asLatex a ++ "\\cdot" ++ "\\left(" ++ asLatex b ++ "\\right)" 633 | 634 | _ -> 635 | asLatex a ++ "\\cdot " ++ asLatex b 636 | 637 | Div a b -> 638 | "\\frac{" ++ asLatex a ++ "}{" ++ asLatex b ++ "}" 639 | 640 | -- only need to take care of the parentheses around the base. 641 | Pow a b -> 642 | let 643 | displayb = 644 | "^{" ++ asLatex b ++ "}" 645 | in 646 | if isTrig a then 647 | -- if it's a trig functino then we put the power in between the operator and the content 648 | trigPower a displayb 649 | 650 | else if shouldHaveParentheses (Pow a b) a then 651 | -- else we just do the regular stuff 652 | "\\left(" ++ asLatex a ++ "\\right)" ++ displayb 653 | 654 | else 655 | asLatex a ++ displayb 656 | 657 | Ln a -> 658 | "\\ln\\left(" ++ asLatex a ++ "\\right)" 659 | 660 | Sqrt f -> 661 | "\\sqrt{" ++ asLatex f ++ "}" 662 | 663 | Negative f -> 664 | "-" ++ asLatex f 665 | 666 | trig -> 667 | trigToString trig 668 | |> (\( operator, content ) -> operator ++ content) 669 | 670 | 671 | 672 | -- helper functions for asLatex. Mainly trig stuff lol 673 | -- isTrig is useful because power functions are represented differently when it's a trig function 674 | 675 | 676 | isTrig : Expr -> Bool 677 | isTrig a = 678 | case a of 679 | Sin _ -> 680 | True 681 | 682 | Csc _ -> 683 | True 684 | 685 | Cos _ -> 686 | True 687 | 688 | Sec _ -> 689 | True 690 | 691 | Tan _ -> 692 | True 693 | 694 | Cot _ -> 695 | True 696 | 697 | _ -> 698 | False 699 | 700 | 701 | 702 | -- displays exponents when it's a trig function 703 | 704 | 705 | trigPower : Expr -> String -> String 706 | trigPower trig power = 707 | let 708 | ( operator, content ) = 709 | trigToString trig 710 | in 711 | operator ++ power ++ content 712 | 713 | 714 | trigToString : Expr -> ( String, String ) 715 | trigToString trig = 716 | let 717 | latexA a = 718 | "\\left(" ++ asLatex a ++ "\\right)" 719 | in 720 | case trig of 721 | Sin a -> 722 | ( "\\sin", latexA a ) 723 | 724 | Csc a -> 725 | ( "\\csc", latexA a ) 726 | 727 | Cos a -> 728 | ( "\\cos", latexA a ) 729 | 730 | Sec a -> 731 | ( "\\sec", latexA a ) 732 | 733 | Tan a -> 734 | ( "\\tan", latexA a ) 735 | 736 | Cot a -> 737 | ( "\\cot", latexA a ) 738 | 739 | _ -> 740 | ( "", "" ) 741 | 742 | 743 | {-| Parentheses checker 744 | 745 | e.g. `asLatex <| Mult (Add a b) (Sub c d)` should be `(a + b)(c - d)` 746 | 747 | This function helps to guarantee that nested binary operations lower in precedence than the parent 748 | will have parentheses around them 749 | 750 | Note that `asLatex <| Mult (Var "x") (Sub c d)` would output `x(c - d)` 751 | **Only binary operations are considered! (except the Negative of course)** 752 | 753 | -} 754 | shouldHaveParentheses : Expr -> Expr -> Bool 755 | shouldHaveParentheses parent child = 756 | let 757 | precedenceLevel expr = 758 | case expr of 759 | Add _ _ -> 760 | Just 1 761 | 762 | Sub _ _ -> 763 | Just 1 764 | 765 | Div _ _ -> 766 | Just 2 767 | 768 | Mult _ _ -> 769 | Just 2 770 | 771 | Pow _ _ -> 772 | Just 3 773 | 774 | Negative a -> 775 | precedenceLevel a 776 | |> Maybe.map (\x -> x + 2) 777 | 778 | -- disregard unary operations 779 | _ -> 780 | Nothing 781 | 782 | relativePrecedence = 783 | Maybe.map2 (-) (precedenceLevel parent) (precedenceLevel child) 784 | in 785 | case relativePrecedence of 786 | Just n -> 787 | n > 0 788 | 789 | _ -> 790 | False 791 | 792 | 793 | errorToString : MathError -> String 794 | errorToString err = 795 | case err of 796 | DivisionByZero -> 797 | "Division by zero!" 798 | 799 | ExtraVariable str -> 800 | "Extra variable! [" ++ str ++ "]" 801 | 802 | ParserErrors errors -> 803 | {--} 804 | -- especially in the oneOf parsers, we will get a bunch of errors stating that each one of the parsers failed. 805 | -- we only need to display the last one 806 | case lastElem errors of 807 | Just e -> 808 | "Parser Error: " ++ e 809 | 810 | Nothing -> 811 | "Unknown Parser error!" 812 | 813 | --} 814 | {-- 815 | -- This is for showing ALL the errors 816 | List.foldl (\error acc -> acc ++ ", " ++ error) "[" errors 817 | -- |> (\s -> s ++ "]") 818 | --} 819 | DerivativeError str -> 820 | "Derivative Error! " ++ str 821 | 822 | 823 | 824 | -- used for ParserErrors 825 | -- this function is taken from [this reddit post](https://www.reddit.com/r/elm/comments/4j2fg6/finding_the_last_list_element/d33g6ae/) 826 | 827 | 828 | lastElem : List a -> Maybe a 829 | lastElem = 830 | List.foldl (Just >> always) Nothing 831 | 832 | 833 | 834 | ------------------------------------ 835 | -- PARSER 836 | ------------------------------------ 837 | 838 | 839 | {-| Advanced type aliases so we don't have to write out as much 840 | -} 841 | type alias MyParser a = 842 | Parser Context Problem a 843 | 844 | 845 | type Problem 846 | = UnknownOperator 847 | | BadVariable VariableProblem -- for variable parser 848 | | BadNumber 849 | | BadEnding -- when Parser.end fails 850 | | ExpectingExpression String -- when we're parsing symbols we need a problem type 851 | | ExpectingOperation String 852 | | ExpectingSymbol String 853 | | ExpectingNoSpace -- for multiplication 854 | 855 | 856 | type VariableProblem 857 | = ExpectingAlpha 858 | | Underscore 859 | | LeftBracket 860 | | RightBracket 861 | | ExpectedAlphaNum 862 | 863 | 864 | type Context 865 | = Expression 866 | | BackslashVariable 867 | | RegularVariable 868 | | Parentheses 869 | 870 | 871 | type alias DeadEnd = 872 | Parser.DeadEnd Context Problem 873 | 874 | 875 | {-| Advanced Pratt Parser type alias 876 | -} 877 | type alias PrattConfig a = 878 | Pratt.Config Context Problem a 879 | 880 | 881 | 882 | -- actually running the parser on a latex string 883 | 884 | 885 | fromLatex : String -> Result MathError Expr 886 | fromLatex str = 887 | if str == "" then 888 | initExpr 889 | 890 | else 891 | String.trim str 892 | |> Parser.run parser 893 | |> Result.mapError toMathErrors 894 | 895 | 896 | initExpr : Result MathError Expr 897 | initExpr = 898 | Err <| ParserErrors [ "Waiting for expression" ] 899 | 900 | 901 | 902 | -- top level parser - make sure it reaches the end of the string 903 | 904 | 905 | parser : MyParser Expr 906 | parser = 907 | Parser.succeed identity 908 | |= expression 909 | |. Parser.end BadEnding 910 | 911 | 912 | 913 | -- Thanks to the Pratt Parser for existing! 914 | 915 | 916 | expression : MyParser Expr 917 | expression = 918 | Parser.inContext Expression <| 919 | Pratt.expression 920 | { oneOf = 921 | [ negationCheck 922 | , sqrt 923 | , division 924 | , parentheses 925 | , Pratt.prefix 5 cosine Cos 926 | , Pratt.prefix 5 sine Sin 927 | , Pratt.prefix 5 cosecant Csc 928 | , Pratt.prefix 5 secant Sec 929 | , Pratt.prefix 5 tangent Tan 930 | , Pratt.prefix 5 cotangent Cot 931 | , Pratt.prefix 5 natLog Ln 932 | , Pratt.literal variable 933 | , Pratt.literal constant 934 | 935 | -- sometimes we'll have x^{3x-1}, and this parses the braces. 936 | -- We'll have to hope that an exponent is the only real use case of this parser tho rip 937 | -- I'm pretty confident?? 938 | , powArgument 939 | , \_ -> Parser.problem UnknownOperator 940 | ] 941 | , andThenOneOf = 942 | [ Pratt.infixLeft 1 (Parser.symbol (Token "+" (ExpectingOperation "+"))) Add 943 | , Pratt.infixLeft 1 (Parser.symbol (Token "-" (ExpectingOperation "-"))) Sub 944 | , Pratt.infixLeft 2 (Parser.symbol (Token "\\cdot" (ExpectingOperation "\\cdot"))) Mult 945 | 946 | -- allows parsing of expressions like 3x 947 | , Pratt.infixLeft 2 (Parser.symbol (Token "" ExpectingNoSpace)) Mult 948 | , Pratt.infixRight 4 (Parser.symbol (Token "^" (ExpectingOperation "^"))) Pow 949 | ] 950 | , spaces = Parser.spaces 951 | } 952 | 953 | 954 | 955 | -- negation only goes to the next term 956 | 957 | 958 | negationCheck : PrattConfig Expr -> MyParser Expr 959 | negationCheck = 960 | let 961 | negationToken = 962 | Token "-" (ExpectingOperation "-") 963 | in 964 | Pratt.prefix 3 (Parser.symbol negationToken) negate 965 | 966 | 967 | {-| Basic trigonometry chompers 968 | -} 969 | sine : MyParser () 970 | sine = 971 | unary "\\sin" 972 | 973 | 974 | cosine : MyParser () 975 | cosine = 976 | unary "\\cos" 977 | 978 | 979 | cosecant : MyParser () 980 | cosecant = 981 | unary "\\csc" 982 | 983 | 984 | secant : MyParser () 985 | secant = 986 | unary "\\sec" 987 | 988 | 989 | tangent : MyParser () 990 | tangent = 991 | unary "\\tan" 992 | 993 | 994 | cotangent : MyParser () 995 | cotangent = 996 | unary "\\cot" 997 | 998 | 999 | natLog : MyParser () 1000 | natLog = 1001 | unary "\\ln" 1002 | 1003 | 1004 | 1005 | -- helper function for unary operations 1006 | 1007 | 1008 | unary : String -> MyParser () 1009 | unary keyword = 1010 | Parser.succeed () 1011 | |. Parser.keyword (Token keyword (ExpectingExpression keyword)) 1012 | |. Parser.spaces 1013 | 1014 | 1015 | 1016 | -- because sqrt is not a simple prefix operation (it has braces) we need to use more stuff 1017 | 1018 | 1019 | sqrt : PrattConfig Expr -> MyParser Expr 1020 | sqrt config = 1021 | Parser.succeed Sqrt 1022 | |. Parser.symbol (Token "\\sqrt" (ExpectingExpression "\\sqrt")) 1023 | |. Parser.symbol (Token "{" (ExpectingSymbol "{")) 1024 | |= Pratt.subExpression 0 config 1025 | |. Parser.symbol (Token "}" (ExpectingSymbol "}")) 1026 | 1027 | 1028 | division : PrattConfig Expr -> MyParser Expr 1029 | division config = 1030 | Parser.succeed Div 1031 | |. Parser.keyword (Token "\\frac" (ExpectingExpression "\\frac")) 1032 | |. Parser.symbol (Token "{" (ExpectingSymbol "{")) 1033 | |= Pratt.subExpression 0 config 1034 | |. Parser.symbol (Token "}" (ExpectingSymbol "}")) 1035 | |. Parser.symbol (Token "{" (ExpectingSymbol "{")) 1036 | |= Pratt.subExpression 0 config 1037 | |. Parser.symbol (Token "}" (ExpectingSymbol "}")) 1038 | 1039 | 1040 | 1041 | -- we accept both () and [] parentheses 1042 | 1043 | 1044 | parentheses : PrattConfig Expr -> MyParser Expr 1045 | parentheses config = 1046 | Parser.inContext Parentheses <| 1047 | Parser.succeed identity 1048 | |. Parser.keyword (Token "\\left" (ExpectingExpression "\\left")) 1049 | |= Parser.oneOf 1050 | [ Parser.succeed identity 1051 | |. Parser.symbol (Token "(" (ExpectingSymbol "(")) 1052 | |= Pratt.subExpression 0 config 1053 | |. Parser.keyword (Token "\\right" (ExpectingExpression "\\right")) 1054 | |. Parser.symbol (Token ")" (ExpectingSymbol ")")) 1055 | , Parser.succeed identity 1056 | |. Parser.symbol (Token "[" (ExpectingSymbol "[")) 1057 | |= Pratt.subExpression 0 config 1058 | |. Parser.keyword (Token "\\right" (ExpectingExpression "\\right")) 1059 | |. Parser.symbol (Token "]" (ExpectingSymbol "]")) 1060 | 1061 | -- , Parser.problem "I am expecting a pair of parentheses but that failed - I can only handle () and []! If you are trying to type in absolute value, I don't support that" 1062 | ] 1063 | 1064 | 1065 | {-| Variables 1066 | 1067 | Any alpha character 1068 | Any alpha character followed by an underscore and alphanumeric (e.g. a_1 or a_b) 1069 | Any alpha character followed by an underscore with anything in {} (e.g. a_{thingy\pi 123} 1070 | One of the greek letters (e.g. \theta, \phi, etc) that are not from a "list" of otherwise defined tokens 1071 | 1072 | ALSO HOLY COW THE PARSER ONEOF COMBINATIONS WORKS LOL I CANT BELIEVE IT 1073 | 1074 | -} 1075 | variable : MyParser Expr 1076 | variable = 1077 | Parser.succeed Var 1078 | |= Parser.oneOf 1079 | [ Parser.succeed () 1080 | |. Parser.chompIf Char.isAlpha (BadVariable ExpectingAlpha) 1081 | |. Parser.oneOf 1082 | [ Parser.chompIf (\c -> c == '_') (BadVariable Underscore) 1083 | |. Parser.oneOf 1084 | [ Parser.chompIf (\c -> c == '{') (BadVariable LeftBracket) 1085 | |. Parser.chompWhile (\c -> not (c == '}')) 1086 | |. Parser.chompIf (\c -> c == '}') (BadVariable RightBracket) 1087 | , Parser.chompIf Char.isAlphaNum (BadVariable ExpectedAlphaNum) 1088 | ] 1089 | , Parser.succeed () 1090 | ] 1091 | |> Parser.getChompedString 1092 | |> Parser.inContext RegularVariable 1093 | , Parser.variable 1094 | { start = \c -> c == '\\' 1095 | , inner = Char.isAlpha 1096 | , reserved = Set.fromList [ "\\cdot", "\\frac", "\\left", "\\right" ] 1097 | , expecting = BadVariable ExpectingAlpha 1098 | } 1099 | |> Parser.inContext BackslashVariable 1100 | ] 1101 | 1102 | 1103 | 1104 | -- Custom parser to only parser numbers!! 1105 | -- the elm Parser.number also parses "e" as the exponent which messes things such as 3e^{5x} up a lot, and it's annoying 1106 | -- Good thing the Elm Parser is so flexible! 1107 | 1108 | 1109 | constant : MyParser Expr 1110 | constant = 1111 | Parser.getChompedString (Parser.chompWhile (\c -> Char.isDigit c || c == '.')) 1112 | |> Parser.map String.toFloat 1113 | |> Parser.andThen 1114 | (\num -> 1115 | case num of 1116 | Just n -> 1117 | Parser.succeed n 1118 | 1119 | Nothing -> 1120 | Parser.problem BadNumber 1121 | ) 1122 | |> Parser.map Const 1123 | 1124 | 1125 | powArgument : PrattConfig Expr -> MyParser Expr 1126 | powArgument config = 1127 | Parser.succeed identity 1128 | |. Parser.symbol (Token "{" (ExpectingSymbol "{")) 1129 | |= Pratt.subExpression 0 config 1130 | |. Parser.symbol (Token "}" (ExpectingSymbol "}")) 1131 | 1132 | 1133 | toMathErrors : List DeadEnd -> MathError 1134 | toMathErrors deadends = 1135 | List.map deadendToString deadends 1136 | |> ParserErrors 1137 | 1138 | 1139 | deadendToString : DeadEnd -> String 1140 | deadendToString deadend = 1141 | case deadend.problem of 1142 | UnknownOperator -> 1143 | "There is either an unknown operator, we're waiting for you to fill out an argument, or it's a mistake in the code." 1144 | 1145 | BadVariable issue -> 1146 | case issue of 1147 | ExpectingAlpha -> 1148 | if List.member BackslashVariable (List.map .context deadend.contextStack) then 1149 | "I was trying to parse a backslash variable, but either I didn't see a backslash or there were non-alpha characters in the name" ++ withLocation deadend 1150 | 1151 | else 1152 | "I need variables start off with only alpha characters!" ++ withLocation deadend 1153 | 1154 | Underscore -> 1155 | "Expecting something in variable subscript" ++ withLocation deadend 1156 | 1157 | LeftBracket -> 1158 | "Uh oh, we're expecting a left bracket when parsing a variable, but this isn't your fault. Please click \" More Info\" to learn more" ++ withLocation deadend 1159 | 1160 | RightBracket -> 1161 | "Uh oh, we're expecting a right bracket when parsing a variable, but this isn't your fault. Please click \" More Info\" to learn more" ++ withLocation deadend 1162 | 1163 | ExpectedAlphaNum -> 1164 | "Variable subscripts can only contain alphanumeric numbers" ++ withLocation deadend 1165 | 1166 | BadNumber -> 1167 | "Error parsing a number" ++ withLocation deadend 1168 | 1169 | BadEnding -> 1170 | "Couldn't finish parsing the expression completely!" ++ withLocation deadend 1171 | 1172 | ExpectingExpression str -> 1173 | "Expecting expression: " ++ str ++ withLocation deadend 1174 | 1175 | ExpectingOperation str -> 1176 | "Expecting operation: " ++ str ++ withLocation deadend 1177 | 1178 | ExpectingSymbol str -> 1179 | "Expecting symbol: " ++ str ++ withLocation deadend 1180 | 1181 | ExpectingNoSpace -> 1182 | "Expecting no space for multiplication" ++ withLocation deadend 1183 | 1184 | 1185 | withLocation : DeadEnd -> String 1186 | withLocation deadend = 1187 | " (column: " ++ String.fromInt deadend.col ++ ")" 1188 | -------------------------------------------------------------------------------- /src/Ports.elm: -------------------------------------------------------------------------------- 1 | port module Ports exposing (changedLatex, clear) 2 | 3 | -- javascript sends us a changedLatex message when the mathquill API detects an edit in the InputMath 4 | 5 | 6 | port changedLatex : (String -> msg) -> Sub msg 7 | 8 | 9 | 10 | -- when the clear button is set we send a message to javascript so they can use the mathquill API to clear the input 11 | 12 | 13 | port clear : () -> Cmd msg 14 | -------------------------------------------------------------------------------- /src/assets/fonts/Changes: -------------------------------------------------------------------------------- 1 | CM Unicode 0.7.0 (June 18 2009) 2 | ================= 3 | o License changed to OFL 1.1 4 | o Converted to lookups for Advanced Typography 5 | o Changed building of accented characters, it is now based on anchors 6 | o Added special accents for capital letters 7 | o Added small serifs to U+26A in sans-serif fonts 8 | o Reencoded U+478 and U+479 as U+A46A, U+A46B 9 | o Kerning copied to built accented characters 10 | 11 | CM Unicode 0.6.3a (March 14 2008) 12 | ================= 13 | o Bug fixes: 14 | - wrong ucircumflex and udieresis in CMUTypewriter-Regular, 15 | CMUTypewriter-Oblique, CMUTypewriter-LightOblique 16 | - wrong advanced width of U+044F in CMUSerif-Italic 17 | - empty M in CMUSansSerif-Oblique 18 | - changed encoding of U+2116 in *.enc files 19 | 20 | CM Unicode 0.6.3 (March 16 2007) 21 | ================ 22 | o Added Latin Extended-A and Latin Extended-B characters to 23 | CMUSerif-Roman from Victor Carbajo 24 | o Added glyphs from t2d encoded lh fonts 25 | o Regenerated by newer fontforge which fixes an issue with "dotlessj" 26 | 27 | CM Unicode 0.6.2 (March 02 2007) 28 | ================ 29 | o Added anchors to phonetic characters 30 | o Added 18 pixel bitmap font to CMUBright-Roman, fixed other sizes 31 | o Swapped "uni1FBC", "uni1FCC", "uni1FFC" and "uni1FBC.alt", "uni1FCC.alt", 32 | "uni1FFC.alt" (suggested by Alexey Kryukov), removed relevant substitution 33 | with "case" tag, added alternative set of capital letters with mute iota 34 | o Patched lh fonts to make U+0428 symmetric, also changed U+0429 35 | o Added stylistic set 1 with some Latin accented letters based on Vietnamese 36 | ones and capital letters with adscript mute iota 37 | o Added Greek small capitals to CMUSerif-Roman, CMUSerif-Bold, CMUSansSerif, 38 | CMUSansSerif-Bold, CMUTypewriter-Regular 39 | o Added 'kern' GPOS tables to languages other than "latn{dflt}" 40 | 41 | CM Unicode 0.6.1 (November 10 2006) 42 | ================ 43 | o Added ligatures for "i", "j" + combining accents, "Aogonek" 44 | o Added anchors 45 | o Reencoded "femaleuncrossed" as "uni26B2", "uni2040" as "uni2322", 46 | "uni0311" as "tieaccentlowercase", "cyrflex" as "uni0311" 47 | o Added 14 and 16 pixel fonts to CMUBright-Roman, regenerated 48 | embedded bitmap fonts 49 | o Changed script and language tags (suggested by Alexey Kryukov) 50 | o Added "uni1FEE" as reference to "uni0385", "figuredash" 51 | o Reencoded accented Russian vowels 52 | o Retraced CMUSansSerif-Bold 53 | o Added substitution from "uni1FB3", "uni1FBC", "uni1FC3", 54 | "uni1FCC", "uni1FF3", "uni1FFC" to "uni1FBC.alt", "uni1FCC.alt", 55 | "uni1FFC.alt" with "case" tag (suggested by Alexey Kryukov) 56 | o Further manual correction of badly traced glyphs from 57 | CMUSerif-Roman, CMUSerif-Italic, CMUSerif-BoldItalic, 58 | CMUSansSerif-Bold, CMUSansSerif-BoldOblique, CMUBright-Roman 59 | fonts 60 | 61 | CM Unicode 0.6.0 (June 28 2006) 62 | ================ 63 | o Added Vietnamese glyphs from vnr fonts. Characters existed in ec 64 | fonts added as local alternatives 65 | o Changed position of accents in "atilde", "amacron", "otilde", 66 | "ntilde", "umacron", "omacron", "aemacron", "uni1E7D", "etilde", 67 | "emacron", "afii10831", "afii10832" 68 | o Corrected "u" and "y" in CMUClassicalSerif-Italic 69 | o Changed shape of "afii10063" to "afii10068" + "macron" 70 | o Fixed Cyrillic small capital characters in CMUConcrete-Roman 71 | o Used names with suffixes for glyph variants. Type 1 fonts now 72 | require at least Freetype 2.2 73 | o Set OS2 Values WinAscent, WinDescent, HHeadAscent and HHeadDescent 74 | from bounding box of ec fonts. TypoLineGap and HHeadLineGap are set 75 | to 200 (20% of em) as advised by Recommendations for OpenType Fonts. 76 | The OpenType fonts now have more condensed line spacing 77 | o Used lh fonts 3.5.4 78 | o Fixed some badly traced glyphs (manually edited) from 79 | CMUSerif-Roman, CMUSansSerif, CMUSansSerif-Oblique, CMUBright-Roman, 80 | CMUBright-Oblique, CMUBright-Bold fonts, look at post_*.sfd files 81 | o Added "locl" substitution from "beta", "gamma", "theta", "lambda", 82 | "chi", "omega" to IPA variants imported from tipa fonts for Latin 83 | alphabet 84 | 85 | CM Unicode 0.5.0 (March 01 2006) 86 | ================ 87 | o Removed extra space from name of "CMU Concrete Bold Extended Roman" 88 | o Added CM Bright font family and "Typewriter Text Light" fonts (8 fonts) 89 | o Added accented Russian vowels 90 | o Added glyphs from lb fonts 91 | o Built yet more extended Latin characters 92 | o Renamed "babygamma" as "babygammaold" not to interfere with "rams horn" 93 | o Font family name for "CMUTypewriter-Oblique" changed to "CMU Typewriter Text" 94 | o Added quotereversed, uni201F, uni01A7, uni01A8, uni02C1 95 | o Added uni1FBD and uni1FFD as references 96 | o Changed font and family name for "CMUSerif-UnslantedItalic" to 97 | "CMUSerif-UprightItalic" 98 | o Added space characters: uni2000...uni200D 99 | o Added longs and florin to most fonts 100 | 101 | CM Unicode 0.4.3 (December 07 2005) 102 | ================ 103 | o Copied some combining glyphs to spacing ones for compatibility with TeX 104 | o Changed simplification rules in mergefonts.pe 105 | o Non-unicode glyphs reencoded into Private Use Area 106 | o Added small capitals for Cyrillic and Latin characters to some fonts 107 | o Copied afii10063 from CMUSerif-Italic to CMUClassicalSerif-Italic 108 | o Reencoded acrophonic Greek numbers 109 | o Reencoded some glyphs accordingly upcoming Unicode 5.0 110 | o Added a workaround for fractions in Serif Bold fonts 111 | o Built uni0326 from comma, rebuilt Scommaaccent, scommaaccent, uni021A, 112 | uni021B using uni0326 113 | 114 | CM Unicode 0.4.2 (September 20 2005) 115 | ================ 116 | o Substituted some glyphs (numerals, basic Latin alphabet and some others) from 117 | Blue Sky fonts when available 118 | o Built yet more extended Latin characters 119 | o Built uni0186 from C and uni0254 from c for fonts without IPA 120 | o Added OpenType substitution for old-style numerals (Thanks to Cody Boisclair) 121 | 122 | CM Unicode 0.4.1 (May 25 2005) 123 | ================ 124 | o Removed Apple Advanced Typography tables from opentype fonts 125 | o Reverted nexusleftside and nexusrightside in g.enc 126 | o Properly reencoded strokes in rx.enc 127 | o Used guillemets from lh fonts as default, the ones from ec fonts substituted 128 | with GSUB locl tag 129 | o Corrected uni0329 130 | o Built yet more phonetic symbols 131 | 132 | CM Unicode 0.4.0 (May 03 2005) 133 | ================ 134 | o Added Concrete font family 135 | o Reencoded some symbols accordingly Unicode 4.1 136 | o Merged into uc (ux) fonts from the lh fonts 137 | o Set width of combining glyphs to zero in proportional width fonts 138 | o Used leipzig shape of Greek letters in serif italic fonts, 139 | the old one is moved to CMUClassicalSerif-Italic 140 | o Rebuilt uni1FBC, uni1FCC, uni1FFC placing mute iota under a glyph 141 | o Built capital Greek polytonic glyphs in proportional width fonts 142 | o Built several accented Latin glyphs 143 | o Built IPA digraphs: uni02A3, uni02A5, uni02A8, uni02A9, uni02AA, uni02AB 144 | o Built several phonetic symbols 145 | o Reencoded CYREPS as uni0190 and cyreps as uni0190 in rx.enc 146 | o Merged changes from Alexey Kryukov into g.enc 147 | o Several accents in tc.enc encoded as capital accents 148 | o Used neutral shape for quotesingle from tc fonts 149 | 150 | CM Unicode 0.3.2 (Mar 28 2005) 151 | ================ 152 | o Reencoded Serbian italic glyphs 153 | o Made lowercase monotonic accented Greek glyphs as references to polytonic 154 | ones 155 | o Added Delta.greek, Omega.greek and mu.greek as references to unicode encoded 156 | glyphs 157 | o Added several composite Latin glyphs 158 | o Removed tipabs10 and tipxbs10 from SansSerif-BoldOblique 159 | o acc_height changed to 90/36pt in ectb.mf, ectx.mf, tctb.mf, tctx.mf in order 160 | to shift up accents. Aring glyph is built using fontforge. 161 | 162 | CM Unicode 0.3.1 (Mar 09 2005) 163 | ================ 164 | o Reverted tracing options for Serif Italic fonts with a workaround for fractions 165 | o Changed tracing options for SansSerif-DemiCondensed to produce more smooth 166 | outlines 167 | o Regenerated by the fontforge from CVS which fixes the positions of accented eta 168 | glyphs in otf files 169 | 170 | CM Unicode 0.3.0 (Feb 28 2005) 171 | ================ 172 | o License changed for X11 with an exception for fonts 173 | o Fixed width of ellipsis in proportional fonts 174 | o Changed magnification of italics serif fonts, fixes a bug with onehalf 175 | o Added IPA symbols from tipa fonts 176 | o changed slope of the Greek glyphs in italics, roman slanted and typewriter 177 | text fonts 178 | o Added 10 (6 unicode) Cyrillic extended glyphs from lc fonts 179 | 180 | CM Unicode 0.2.2 (Dec 22 2004) 181 | ================ 182 | o Rebuilt by fontforge with fixed bug related to generation of .pfb fonts with 183 | references 184 | o Added ATT tags for substitution of g, d, p and t for Serbian language in 185 | italic fonts 186 | o Built Serbian glyphs "p" and "t" from Cyrillic "i" and "sha" in italic fonts 187 | o Built imacron 188 | 189 | CM Unicode 0.2.1 (Dec 21 2004) 190 | ================ 191 | o created experimental font gtdn1000 which is merged into 192 | CMUSansSerif-DemiCondensed 193 | o gsme1000 and gsxe1000 fonts used instead of gsmn1000 (changed a shape of 194 | epsilon) 195 | o grmu1000 merged into CMUSerif-UnslantedItalic 196 | o created experimental font gtbi1000 which is merged into 197 | CMUTypewriter-BoldItalic 198 | o created experimental font gtbn1000 which is merged into CMUTypewriter-Bold 199 | o changed encoding for Omega and Delta symbols 200 | o renamed macron.ts1 by macronts1 to avoid ambiguity in freetype 201 | o OpenType fonts are also generated 202 | o added ATT substitutions for guillemotleft, guillemotright, emdash 203 | o Added nonbreakingspace as reference to space 204 | 205 | CM Unicode 0.2.0 (Nov 03 2004) 206 | ================ 207 | o TeX fonts are retraced by mftrace with autotrace backend at higher 208 | resolutions. This should create more correct outlines (I hope). 209 | o Added linedrawing characters to Typewriter fonts 210 | o Added ".notdef" glyph as supposed by Adobe 211 | o Generated several Cyrillic and Greek accented glyphs using fontforge 212 | o Changed fontnames for several fonts to conform Adobe conventions 213 | o regenerated by fontforge-20041028 214 | 215 | CM Unicode 0.1.3 (May 11 2004) 216 | ================ 217 | o regenerated by fontforge-20040509 which fixes issues with hints 218 | 219 | CM Unicode 0.1.2 (Dec 09 2003) 220 | ================ 221 | o regenerated by pfaedit-031205 222 | o added two experimental fonts CMUTypewriter-Bold and CMUTypewriter-BoldItalic, 223 | containing Latin and Cyrillic glyphs 224 | o added RoundToInt() to merging script 225 | o redesigned "musicalnote" glyph for monospaced fonts 226 | o changed family name for Typewriter Text Regular 227 | 228 | CM Unicode 0.1.1 (Aug 27 2003) 229 | ================ 230 | o redesigned ellipsis glyph for monospaced fonts 231 | o changed names for Typewriter Text fonts to conform Mac OS X reqirements 232 | o panose value "monospaced" is set for Typewriter Text fonts 233 | o regenerated by pfaedit-030822 234 | 235 | CM Unicode 0.1 (Apr 10 2003) 236 | ============== 237 | o First public release 238 | 239 | 240 | -------------------------------------------------------------------------------- /src/assets/fonts/FAQ: -------------------------------------------------------------------------------- 1 | How to add new glyphs to existing scripts? 2 | 3 | Usually one wants to add accented glyphs. In that case fontforge 4 | script commands (for example, AddAccent, BuildComposite) may be used. 5 | Fontforge can produce more or less satisfactory character. It may be 6 | adjusted by fontforge preferences. For such simple batch editions it 7 | has not to build everything from scratch. You can create simple 8 | fontforge script, for example: 9 | 10 | #!/usr/local/bin/fontforge 11 | fontname=$1 12 | Open(fontname+".sfd") 13 | SetPref("AccentOffsetPercent",5) 14 | SetPref("AccentCenterLowest",0) 15 | SetPref("CharCenterHighest",0) 16 | Select("imacron") 17 | BuildAccented() 18 | Save(fontname+"-my.sfd") 19 | Close() 20 | Quit() 21 | 22 | You may insert here if commands for specific fonts: 23 | 24 | if (font_var == "bl") 25 | SetPref("CharCenterHighest",1) 26 | else 27 | ... 28 | 29 | Look at mergefonts.pe for more examples. 30 | Then run it with name of some sfd font file from 31 | cm-unicode-*-sfd.tar.bz2 without sfd extension, e. g. 32 | 33 | $fontforge -script aaa.ff `basename cmunrm.sfd .sfd` 34 | 35 | Then send me required commands from this script, I shall include them 36 | into mergefonts.pe 37 | 38 | If you are dissatisfied by the quality of glyph created by the 39 | fontforge or you created totally new glyph: 40 | 41 | Create new font with glyphs will be added to cm-unicode and their 42 | dependencies, when these glyphs contain references. 43 | 44 | Save this font with additions with filename containing some prefix 45 | and cm-unicode suffix (basename of sfd file from 46 | cm-unicode-*-sfd.tar.bz2 without initial "cmun"), e. g.: aaarm.sfd 47 | 48 | And send me these sfd files. 49 | 50 | How to print using opentype fonts from KDE 3.5? 51 | 52 | At first install the fonts for ghostscript. 53 | As a workaround for printing with Qt 3.3 call Fontmap.CMU.alias after 54 | Fontmap.CMU in ghostscript's Fontmap file. It would substitute some 55 | fonts. 56 | -------------------------------------------------------------------------------- /src/assets/fonts/FontLog.txt: -------------------------------------------------------------------------------- 1 | CM Unicode 0.7.0 (June 18 2009) 2 | ================= 3 | o License changed to OFL 1.1 4 | o Converted to lookups for Advanced Typography 5 | o Changed building of accented characters, it is now based on anchors 6 | o Added special accents for capital letters 7 | o Added small serifs to U+26A in sans-serif fonts 8 | o Reencoded U+478 and U+479 as U+A46A, U+A46B 9 | o Kerning copied to built accented characters 10 | 11 | CM Unicode 0.6.3a (March 14 2008) 12 | ================= 13 | o Bug fixes: 14 | - wrong ucircumflex and udieresis in CMUTypewriter-Regular, 15 | CMUTypewriter-Oblique, CMUTypewriter-LightOblique 16 | - wrong advanced width of U+044F in CMUSerif-Italic 17 | - empty M in CMUSansSerif-Oblique 18 | - changed encoding of U+2116 in *.enc files 19 | 20 | CM Unicode 0.6.3 (March 16 2007) 21 | ================ 22 | o Added Latin Extended-A and Latin Extended-B characters to 23 | CMUSerif-Roman from Victor Carbajo 24 | o Added glyphs from t2d encoded lh fonts 25 | o Regenerated by newer fontforge which fixes an issue with "dotlessj" 26 | 27 | CM Unicode 0.6.2 (March 02 2007) 28 | ================ 29 | o Added anchors to phonetic characters 30 | o Added 18 pixel bitmap font to CMUBright-Roman, fixed other sizes 31 | o Swapped "uni1FBC", "uni1FCC", "uni1FFC" and "uni1FBC.alt", "uni1FCC.alt", 32 | "uni1FFC.alt" (suggested by Alexey Kryukov), removed relevant substitution 33 | with "case" tag, added alternative set of capital letters with mute iota 34 | o Patched lh fonts to make U+0428 symmetric, also changed U+0429 35 | o Added stylistic set 1 with some Latin accented letters based on Vietnamese 36 | ones and capital letters with adscript mute iota 37 | o Added Greek small capitals to CMUSerif-Roman, CMUSerif-Bold, CMUSansSerif, 38 | CMUSansSerif-Bold, CMUTypewriter-Regular 39 | o Added 'kern' GPOS tables to languages other than "latn{dflt}" 40 | 41 | CM Unicode 0.6.1 (November 10 2006) 42 | ================ 43 | o Added ligatures for "i", "j" + combining accents, "Aogonek" 44 | o Added anchors 45 | o Reencoded "femaleuncrossed" as "uni26B2", "uni2040" as "uni2322", 46 | "uni0311" as "tieaccentlowercase", "cyrflex" as "uni0311" 47 | o Added 14 and 16 pixel fonts to CMUBright-Roman, regenerated 48 | embedded bitmap fonts 49 | o Changed script and language tags (suggested by Alexey Kryukov) 50 | o Added "uni1FEE" as reference to "uni0385", "figuredash" 51 | o Reencoded accented Russian vowels 52 | o Retraced CMUSansSerif-Bold 53 | o Added substitution from "uni1FB3", "uni1FBC", "uni1FC3", 54 | "uni1FCC", "uni1FF3", "uni1FFC" to "uni1FBC.alt", "uni1FCC.alt", 55 | "uni1FFC.alt" with "case" tag (suggested by Alexey Kryukov) 56 | o Further manual correction of badly traced glyphs from 57 | CMUSerif-Roman, CMUSerif-Italic, CMUSerif-BoldItalic, 58 | CMUSansSerif-Bold, CMUSansSerif-BoldOblique, CMUBright-Roman 59 | fonts 60 | 61 | CM Unicode 0.6.0 (June 28 2006) 62 | ================ 63 | o Added Vietnamese glyphs from vnr fonts. Characters existed in ec 64 | fonts added as local alternatives 65 | o Changed position of accents in "atilde", "amacron", "otilde", 66 | "ntilde", "umacron", "omacron", "aemacron", "uni1E7D", "etilde", 67 | "emacron", "afii10831", "afii10832" 68 | o Corrected "u" and "y" in CMUClassicalSerif-Italic 69 | o Changed shape of "afii10063" to "afii10068" + "macron" 70 | o Fixed Cyrillic small capital characters in CMUConcrete-Roman 71 | o Used names with suffixes for glyph variants. Type 1 fonts now 72 | require at least Freetype 2.2 73 | o Set OS2 Values WinAscent, WinDescent, HHeadAscent and HHeadDescent 74 | from bounding box of ec fonts. TypoLineGap and HHeadLineGap are set 75 | to 200 (20% of em) as advised by Recommendations for OpenType Fonts. 76 | The OpenType fonts now have more condensed line spacing 77 | o Used lh fonts 3.5.4 78 | o Fixed some badly traced glyphs (manually edited) from 79 | CMUSerif-Roman, CMUSansSerif, CMUSansSerif-Oblique, CMUBright-Roman, 80 | CMUBright-Oblique, CMUBright-Bold fonts, look at post_*.sfd files 81 | o Added "locl" substitution from "beta", "gamma", "theta", "lambda", 82 | "chi", "omega" to IPA variants imported from tipa fonts for Latin 83 | alphabet 84 | 85 | CM Unicode 0.5.0 (March 01 2006) 86 | ================ 87 | o Removed extra space from name of "CMU Concrete Bold Extended Roman" 88 | o Added CM Bright font family and "Typewriter Text Light" fonts (8 fonts) 89 | o Added accented Russian vowels 90 | o Added glyphs from lb fonts 91 | o Built yet more extended Latin characters 92 | o Renamed "babygamma" as "babygammaold" not to interfere with "rams horn" 93 | o Font family name for "CMUTypewriter-Oblique" changed to "CMU Typewriter Text" 94 | o Added quotereversed, uni201F, uni01A7, uni01A8, uni02C1 95 | o Added uni1FBD and uni1FFD as references 96 | o Changed font and family name for "CMUSerif-UnslantedItalic" to 97 | "CMUSerif-UprightItalic" 98 | o Added space characters: uni2000...uni200D 99 | o Added longs and florin to most fonts 100 | 101 | CM Unicode 0.4.3 (December 07 2005) 102 | ================ 103 | o Copied some combining glyphs to spacing ones for compatibility with TeX 104 | o Changed simplification rules in mergefonts.pe 105 | o Non-unicode glyphs reencoded into Private Use Area 106 | o Added small capitals for Cyrillic and Latin characters to some fonts 107 | o Copied afii10063 from CMUSerif-Italic to CMUClassicalSerif-Italic 108 | o Reencoded acrophonic Greek numbers 109 | o Reencoded some glyphs accordingly upcoming Unicode 5.0 110 | o Added a workaround for fractions in Serif Bold fonts 111 | o Built uni0326 from comma, rebuilt Scommaaccent, scommaaccent, uni021A, 112 | uni021B using uni0326 113 | 114 | CM Unicode 0.4.2 (September 20 2005) 115 | ================ 116 | o Substituted some glyphs (numerals, basic Latin alphabet and some others) from 117 | Blue Sky fonts when available 118 | o Built yet more extended Latin characters 119 | o Built uni0186 from C and uni0254 from c for fonts without IPA 120 | o Added OpenType substitution for old-style numerals (Thanks to Cody Boisclair) 121 | 122 | CM Unicode 0.4.1 (May 25 2005) 123 | ================ 124 | o Removed Apple Advanced Typography tables from opentype fonts 125 | o Reverted nexusleftside and nexusrightside in g.enc 126 | o Properly reencoded strokes in rx.enc 127 | o Used guillemets from lh fonts as default, the ones from ec fonts substituted 128 | with GSUB locl tag 129 | o Corrected uni0329 130 | o Built yet more phonetic symbols 131 | 132 | CM Unicode 0.4.0 (May 03 2005) 133 | ================ 134 | o Added Concrete font family 135 | o Reencoded some symbols accordingly Unicode 4.1 136 | o Merged into uc (ux) fonts from the lh fonts 137 | o Set width of combining glyphs to zero in proportional width fonts 138 | o Used leipzig shape of Greek letters in serif italic fonts, 139 | the old one is moved to CMUClassicalSerif-Italic 140 | o Rebuilt uni1FBC, uni1FCC, uni1FFC placing mute iota under a glyph 141 | o Built capital Greek polytonic glyphs in proportional width fonts 142 | o Built several accented Latin glyphs 143 | o Built IPA digraphs: uni02A3, uni02A5, uni02A8, uni02A9, uni02AA, uni02AB 144 | o Built several phonetic symbols 145 | o Reencoded CYREPS as uni0190 and cyreps as uni0190 in rx.enc 146 | o Merged changes from Alexey Kryukov into g.enc 147 | o Several accents in tc.enc encoded as capital accents 148 | o Used neutral shape for quotesingle from tc fonts 149 | 150 | CM Unicode 0.3.2 (Mar 28 2005) 151 | ================ 152 | o Reencoded Serbian italic glyphs 153 | o Made lowercase monotonic accented Greek glyphs as references to polytonic 154 | ones 155 | o Added Delta.greek, Omega.greek and mu.greek as references to unicode encoded 156 | glyphs 157 | o Added several composite Latin glyphs 158 | o Removed tipabs10 and tipxbs10 from SansSerif-BoldOblique 159 | o acc_height changed to 90/36pt in ectb.mf, ectx.mf, tctb.mf, tctx.mf in order 160 | to shift up accents. Aring glyph is built using fontforge. 161 | 162 | CM Unicode 0.3.1 (Mar 09 2005) 163 | ================ 164 | o Reverted tracing options for Serif Italic fonts with a workaround for fractions 165 | o Changed tracing options for SansSerif-DemiCondensed to produce more smooth 166 | outlines 167 | o Regenerated by the fontforge from CVS which fixes the positions of accented eta 168 | glyphs in otf files 169 | 170 | CM Unicode 0.3.0 (Feb 28 2005) 171 | ================ 172 | o License changed for X11 with an exception for fonts 173 | o Fixed width of ellipsis in proportional fonts 174 | o Changed magnification of italics serif fonts, fixes a bug with onehalf 175 | o Added IPA symbols from tipa fonts 176 | o changed slope of the Greek glyphs in italics, roman slanted and typewriter 177 | text fonts 178 | o Added 10 (6 unicode) Cyrillic extended glyphs from lc fonts 179 | 180 | CM Unicode 0.2.2 (Dec 22 2004) 181 | ================ 182 | o Rebuilt by fontforge with fixed bug related to generation of .pfb fonts with 183 | references 184 | o Added ATT tags for substitution of g, d, p and t for Serbian language in 185 | italic fonts 186 | o Built Serbian glyphs "p" and "t" from Cyrillic "i" and "sha" in italic fonts 187 | o Built imacron 188 | 189 | CM Unicode 0.2.1 (Dec 21 2004) 190 | ================ 191 | o created experimental font gtdn1000 which is merged into 192 | CMUSansSerif-DemiCondensed 193 | o gsme1000 and gsxe1000 fonts used instead of gsmn1000 (changed a shape of 194 | epsilon) 195 | o grmu1000 merged into CMUSerif-UnslantedItalic 196 | o created experimental font gtbi1000 which is merged into 197 | CMUTypewriter-BoldItalic 198 | o created experimental font gtbn1000 which is merged into CMUTypewriter-Bold 199 | o changed encoding for Omega and Delta symbols 200 | o renamed macron.ts1 by macronts1 to avoid ambiguity in freetype 201 | o OpenType fonts are also generated 202 | o added ATT substitutions for guillemotleft, guillemotright, emdash 203 | o Added nonbreakingspace as reference to space 204 | 205 | CM Unicode 0.2.0 (Nov 03 2004) 206 | ================ 207 | o TeX fonts are retraced by mftrace with autotrace backend at higher 208 | resolutions. This should create more correct outlines (I hope). 209 | o Added linedrawing characters to Typewriter fonts 210 | o Added ".notdef" glyph as supposed by Adobe 211 | o Generated several Cyrillic and Greek accented glyphs using fontforge 212 | o Changed fontnames for several fonts to conform Adobe conventions 213 | o regenerated by fontforge-20041028 214 | 215 | CM Unicode 0.1.3 (May 11 2004) 216 | ================ 217 | o regenerated by fontforge-20040509 which fixes issues with hints 218 | 219 | CM Unicode 0.1.2 (Dec 09 2003) 220 | ================ 221 | o regenerated by pfaedit-031205 222 | o added two experimental fonts CMUTypewriter-Bold and CMUTypewriter-BoldItalic, 223 | containing Latin and Cyrillic glyphs 224 | o added RoundToInt() to merging script 225 | o redesigned "musicalnote" glyph for monospaced fonts 226 | o changed family name for Typewriter Text Regular 227 | 228 | CM Unicode 0.1.1 (Aug 27 2003) 229 | ================ 230 | o redesigned ellipsis glyph for monospaced fonts 231 | o changed names for Typewriter Text fonts to conform Mac OS X reqirements 232 | o panose value "monospaced" is set for Typewriter Text fonts 233 | o regenerated by pfaedit-030822 234 | 235 | CM Unicode 0.1 (Apr 10 2003) 236 | ============== 237 | o First public release 238 | 239 | 240 | -------------------------------------------------------------------------------- /src/assets/fonts/Fontmap.CMU: -------------------------------------------------------------------------------- 1 | /CMUBright-Bold (cmunbbx.ttf) ; 2 | /CMUSerif-BoldItalic (cmunbi.ttf) ; 3 | /CMUSerif-BoldSlanted (cmunbl.ttf) ; 4 | /CMUBright-Oblique (cmunbmo.ttf) ; 5 | /CMUBright-Roman (cmunbmr.ttf) ; 6 | /CMUBright-SemiboldOblique (cmunbso.ttf) ; 7 | /CMUBright-Semibold (cmunbsr.ttf) ; 8 | /CMUTypewriter-Light (cmunbtl.ttf) ; 9 | /CMUTypewriter-LightOblique (cmunbto.ttf) ; 10 | /CMUSerif-Bold (cmunbx.ttf) ; 11 | /CMUBright-BoldOblique (cmunbxo.ttf) ; 12 | /CMUClassicalSerif-Italic (cmunci.ttf) ; 13 | /CMUTypewriter-Italic (cmunit.ttf) ; 14 | /CMUConcrete-BoldItalic (cmunobi.ttf) ; 15 | /CMUConcrete-Bold (cmunobx.ttf) ; 16 | /CMUConcrete-Roman (cmunorm.ttf) ; 17 | /CMUConcrete-Italic (cmunoti.ttf) ; 18 | /CMUSerif-BoldNonextended (cmunrb.ttf) ; 19 | /CMUSerif-Roman (cmunrm.ttf) ; 20 | /CMUSansSerif-Oblique (cmunsi.ttf) ; 21 | /CMUSerif-RomanSlanted (cmunsl.ttf) ; 22 | /CMUSansSerif-BoldOblique (cmunso.ttf) ; 23 | /CMUSansSerif (cmunss.ttf) ; 24 | /CMUSansSerif-DemiCondensed (cmunssdc.ttf) ; 25 | /CMUTypewriter-Oblique (cmunst.ttf) ; 26 | /CMUSansSerif-Bold (cmunsx.ttf) ; 27 | /CMUTypewriter-Bold (cmuntb.ttf) ; 28 | /CMUSerif-Italic (cmunti.ttf) ; 29 | /CMUTypewriter-Regular (cmuntt.ttf) ; 30 | /CMUTypewriter-BoldItalic (cmuntx.ttf) ; 31 | /CMUSerif-UprightItalic (cmunui.ttf) ; 32 | /CMUTypewriterVariable-Italic (cmunvi.ttf) ; 33 | /CMUTypewriterVariable (cmunvt.ttf) ; 34 | -------------------------------------------------------------------------------- /src/assets/fonts/INSTALL: -------------------------------------------------------------------------------- 1 | Installation for XFree86 (X.Org) 2 | -------------------------------- 3 | 4 | Unpack the archive file containing fonts in some temporal directory, for 5 | example /tmp : 6 | 7 | cd /tmp 8 | tar xzvf cm_unicode-VERSION-pfb.tar.gz 9 | cd cm-unicode-VERSION 10 | 11 | where VERSION is version number of this font pack. 12 | Then create cm-unicode/ directory at the place, where your X stores fonts, for example 13 | /usr/share/fonts : 14 | 15 | mkdir -p /usr/share/fonts/cm-unicode 16 | 17 | You should become root to do it. Then copy font files there: 18 | 19 | cp *.afm /usr/share/fonts/cm-unicode/ 20 | cp *.pfb /usr/share/fonts/cm-unicode/ 21 | 22 | If you are using XFree86 prior to 4.3 you shoul also copy fonts.scale there. 23 | Then change directory to /usr/share/fonts/cm-unicode/ : 24 | 25 | cd /usr/share/fonts/cm-unicode/ 26 | 27 | and do 28 | 29 | mkfontscale # if you are using XFree86-4.3 or later or recent X.Org 30 | mkfontdir 31 | 32 | Currently mkfontscale and mkfontdir may produce errors, so copy 33 | fonts.dir and fonts.scale files supplied into 34 | /usr/share/fonts/cm-unicode/ 35 | 36 | Then add 37 | FontPath "/usr/share/fonts/cm-unicode/" 38 | to "Files" Section of /etc/X11/xorg.conf (/etc/X11/XF86Config). On the 39 | next run X.Org (XFree86) will load these fonts. 40 | 41 | If you are using fontconfig (X.Org, XFree86-4.3, may be installed on 42 | XFree86-4.2) you should add a line 43 | /usr/share/fonts/cm-unicode 44 | to /etc/fonts/fonts.conf or better to /etc/fonts/local.conf then run 45 | 46 | fc-cache 47 | 48 | 49 | Installation for ghostscript 50 | ---------------------------- 51 | (Optional, modern versions of ghostscript retreive information from fontconfig) 52 | 53 | 54 | Assuming that you have rather new ghostscript version like 7.x go to 55 | default ghostscript font directory, typically /usr/share/ghostscript/fonts, then 56 | add links to fonts installed for X or copy them: 57 | 58 | cd /usr/share/ghostscript/fonts 59 | ln -s /usr/share/fonts/cm-unicode/*.afm . 60 | ln -s /usr/share/fonts/cm-unicode/*.pfb . 61 | 62 | Then go to the ghostscript library directory, for example 63 | 64 | cd /usr/share/ghostscript/?.??/lib 65 | 66 | where ?.?? is ghostscript version. Copy Fontmap.CMU from tarball: 67 | 68 | cp /tmp/cm_unicode-VERSION/Fontmap.CMU . 69 | 70 | Then add following line to Fontmap file: 71 | 72 | (Fontmap.CMU) .runlibfile 73 | 74 | Note that pdfwriter from ghostscript versions prior to 8.x does not 75 | understand characters not existing in the encoding. These fonts were 76 | tested with ps2pdf script from AFPL ghostscript-8.14. 77 | 78 | That's all. 79 | -------------------------------------------------------------------------------- /src/assets/fonts/OFL-FAQ.txt: -------------------------------------------------------------------------------- 1 | OFL FAQ - Frequently Asked Questions about the SIL Open Font License (OFL) 2 | Version 1.1 - 26 February 2007 3 | (See http://scripts.sil.org/OFL for updates) 4 | 5 | 6 | 1 ABOUT USING AND DISTRIBUTING FONTS LICENSED UNDER THE OFL 7 | 8 | 1.1 Can I use the fonts in any publication, even embedded in the file? 9 | Yes. You may use them like most other fonts, but unlike some fonts you may include an embedded subset of the fonts in your document. Such use does not require you to include this license or other files (listed in OFL condition 2), nor does it require any type of acknowledgement within the publication. Some mention of the font name within the publication information (such as in a colophon) is usually appreciated. If you wish to include the complete font as a separate file, you should distribute the full font package, including all existing acknowledgements, and comply with the OFL conditions. Of course, referencing or embedding an OFL font in any document does not change the license of the document itself. The requirement for fonts to remain under the OFL does not apply to any document created using the fonts and their derivatives. Similarly, creating any kind of graphic using a font under OFL does not make the resulting artwork subject to the OFL. 10 | 11 | 1.2 Can I make web pages using these fonts? 12 | Yes! Go ahead! Using CSS (Cascading Style Sheets) is recommended. 13 | 14 | 1.3 Can I make the fonts available to others from my web site? 15 | Yes, as long as you meet the conditions of the license (do not sell by itself, include the necessary files, rename Modified Versions, do not abuse the Author(s)' name(s) and do not sublicense). 16 | 17 | 1.4 Can the fonts be included with Free/Libre and Open Source Software collections such as GNU/Linux and BSD distributions? 18 | Yes! Fonts licensed under the OFL can be freely aggregated with software under FLOSS (Free/Libre and Open Source Software) licenses. Since fonts are much more useful aggregated to than merged with existing software, possible incompatibility with existing software licenses is not a problem. You can also repackage the fonts and the accompanying components in a .rpm or .deb package and include them in distro CD/DVDs and online repositories. 19 | 20 | 1.5 I want to distribute the fonts with my program. Does this mean my program also has to be free and open source software? 21 | No. Only the portions based on the font software are required to be released under the OFL. The intent of the license is to allow aggregation or bundling with software under restricted licensing as well. 22 | 23 | 1.6 Can I include the fonts on a CD of freeware or commercial fonts? 24 | Yes, as long some other font or software is also on the disk, so the OFL font is not sold by itself. 25 | 26 | 1.7 Can I sell a software package that includes these fonts? 27 | Yes, you can do this with both the Original Version and a Modified Version. Examples of bundling made possible by the OFL would include: word processors, design and publishing applications, training and educational software, edutainment software, etc. 28 | 29 | 1.8 Why won't the OFL let me sell the fonts alone? 30 | The intent is to keep people from making money by simply redistributing the fonts. The only people who ought to profit directly from the fonts should be the original authors, and those authors have kindly given up potential direct income to distribute their fonts under the OFL. Please honor and respect their contribution! 31 | 32 | 1.9 I've come across a font released under the OFL. How can I easily get more information about the Original Version? How can I know where it stands compared to the Original Version or other Modified Versions? 33 | Consult the copyright statement(s) in the license for ways to contact the original authors. Consult the FONTLOG for information on how the font differs from the Original Version, and get in touch with the various contributors via the information in the acknowledgment section. Please consider using the Original Versions of the fonts whenever possible. 34 | 35 | 1.10 What do you mean in condition 4? Can you provide examples of abusive promotion / endorsement / advertisement vs. normal acknowledgement? 36 | The intent is that the goodwill and reputation of the author(s) should not be used in a way that makes it sound like the original author(s) endorse or approve of a specific Modified Version or software bundle. For example, it would not be right to advertise a word processor by naming the author(s) in a listing of software features, or to promote a Modified Version on a web site by saying "designed by ...". However, it would be appropriate to acknowledge the author(s) if your software package has a list of people who deserve thanks. We realize that this can seem to be a gray area, but the standard used to judge an acknowledgement is that if the acknowledgement benefits the author(s) it is allowed, but if it primarily benefits other parties, or could reflect poorly on the author(s), then it is not. 37 | 38 | 39 | 2 ABOUT MODIFYING OFL LICENSED FONTS 40 | 41 | 2.1 Can I change the fonts? Are there any limitations to what things I can and cannot change? 42 | You are allowed to change anything, as long as such changes do not violate the terms of the license. In other words, you are not allowed to remove the copyright statement(s) from the font, but you could add additional information into it that covers your contribution. 43 | 44 | 2.2 I have a font that needs a few extra glyphs - can I take them from an OFL licensed font and copy them into mine? 45 | Yes, but if you distribute that font to others it must be under the OFL, and include the information mentioned in condition 2 of the license. 46 | 47 | 2.3 Can I charge people for my additional work? In other words, if I add a bunch of special glyphs and/or OpenType/Graphite code, can I sell the enhanced font? 48 | Not by itself. Derivative fonts must be released under the OFL and cannot be sold by themselves. It is permitted, however, to include them in a larger software package (such as text editors, office suites or operating systems), even if the larger package is sold. In that case, you are strongly encouraged, but not required, to also make that derived font easily and freely available outside of the larger package. 49 | 50 | 2.4 Can I pay someone to enhance the fonts for my use and distribution? 51 | Yes. This is a good way to fund the further development of the fonts. Keep in mind, however, that if the font is distributed to others it must be under the OFL. You won't be able to recover your investment by exclusively selling the font, but you will be making a valuable contribution to the community. Please remember how you have benefitted from the contributions of others. 52 | 53 | 2.5 I need to make substantial revisions to the font to make it work with my program. It will be a lot of work, and a big investment, and I want to be sure that it can only be distributed with my program. Can I restrict its use? 54 | No. If you redistribute a Modified Version of the font it must be under the OFL. You may not restrict it in any way. This is intended to ensure that all released improvements to the fonts become available to everyone. But you will likely get an edge over competitors by being the first to distribute a bundle with the enhancements. Again, please remember how you have benefitted from the contributions of others. 55 | 56 | 2.6 Do I have to make any derivative fonts (including source files, build scripts, documentation, etc.) publicly available? 57 | No, but please do share your improvements with others. You may find that you receive more than what you gave in return. 58 | 59 | 2.7 Why can't I use the Reserved Font Name(s) in my derivative font names? I'd like people to know where the design came from. 60 | The best way to acknowledge the source of the design is to thank the original authors and any other contributors in the files that are distributed with your revised font (although no acknowledgement is required). The FONTLOG is a natural place to do this. Reserved Font Name(s) ensure that the only fonts that have the original names are the unmodified Original Versions. This allows designers to maintain artistic integrity while allowing collaboration to happen. It eliminates potential confusion and name conflicts. When choosing a name be creative and avoid names that reuse almost all the same letters in the same order or sound like the original. Keep in mind that the Copyright Holder(s) can allow a specific trusted partner to use Reserved Font Name(s) through a separate written agreement. 61 | 62 | 2.8 What do you mean by "primary name as presented to the user"? Are you referring to the font menu name? 63 | Yes, the requirement to change the visible name used to differentiate the font from others applies to the font menu name and other mechanisms to specify a font in a document. It would be fine, for example, to keep a text reference to the original fonts in the description field, in your modified source file or in documentation provided alongside your derivative as long as no one could be confused that your modified source is the original. But you cannot use the Reserved Font Names in any way to identify the font to the user (unless the Copyright Holder(s) allow(s) it through a separate agreement; see section 2.7). Users who install derivatives ("Modified Versions") on their systems should not see any of the original names ("Reserved Font Names") in their font menus, for example. Again, this is to ensure that users are not confused and do not mistake a font for another and so expect features only another derivative or the Original Version can actually offer. Ultimately, creating name conflicts will cause many problems for the users as well as for the designer of both the Original and Modified versions, so please think ahead and find a good name for your own derivative. Font substitution systems like fontconfig, or application-level font fallback configuration within OpenOffice.org or Scribus, will also get very confused if the name of the font they are configured to substitute to actually refers to another physical font on the user's hard drive. It will help everyone if Original Versions and Modified Versions can easily be distinguished from one another and from other derivatives. The substitution mechanism itself is outside the scope of the license. Users can always manually change a font reference in a document or set up some kind of substitution at a higher level but at the lower level the fonts themselves have to respect the Reserved Font Name(s) requirement to prevent ambiguity. If a substitution is currently active the user should be aware of it. 64 | 65 | 2.9 Am I not allowed to use any part of the Reserved Font Names? 66 | You may not use the words of the font names, but you would be allowed to use parts of words, as long as you do not use any word from the Reserved Font Names entirely. We do not recommend using parts of words because of potential confusion, but it is allowed. For example, if "Foobar" was a Reserved Font Name, you would be allowed to use "Foo" or "bar", although we would not recommend it. Such an unfortunate choice would confuse the users of your fonts as well as make it harder for other designers to contribute. 67 | 68 | 2.10 So what should I, as an author, identify as Reserved Font Names? 69 | Original authors are encouraged to name their fonts using clear, distinct names, and only declare the unique parts of the name as Reserved Font Names. For example, the author of a font called "Foobar Sans" would declare "Foobar" as a Reserved Font Name, but not "Sans", as that is a common typographical term, and may be a useful word to use in a derivative font name. Reserved Font Names should also be single words. A font called "Flowing River" should have Reserved Font Names "Flowing" and "River", not "Flowing River". 70 | 71 | 2.11 Do I, as an author, have to identify any Reserved Font Names? 72 | No, but we strongly encourage you to do so. This is to avoid confusion between your work and Modified versions. You may, however, give certain trusted parties the right to use any of your Reserved Font Names through separate written agreements. For example, even if "Foobar" is a RFN, you could write up an agreement to give company "XYZ" the right to distribute a modified version with a name that includes "Foobar". This allows for freedom without confusion. 73 | 74 | 2.12 Are any names (such as the main font name) reserved by default? 75 | No. That is a change to the license as of version 1.1. If you want any names to be Reserved Font Names, they must be specified after the copyright statement(s). 76 | 77 | 2.13 What is this FONTLOG thing exactly? 78 | It has three purposes: 1) to provide basic information on the font to users and other developers, 2) to document changes that have been made to the font or accompanying files, either by the original authors or others, and 3) to provide a place to acknowledge the authors and other contributors. Please use it! See below for details on how changes should be noted. 79 | 80 | 2.14 Am I required to update the FONTLOG? 81 | No, but users, designers and other developers might get very frustrated at you if you don't! People need to know how derivative fonts differ from the original, and how to take advantage of the changes, or build on them. 82 | 83 | 84 | 3 ABOUT THE FONTLOG 85 | 86 | The FONTLOG can take a variety of formats, but should include these four sections: 87 | 88 | 3.1 FONTLOG for 89 | This file provides detailed information on the font software. This information should be distributed along with the fonts and any derivative works. 90 | 91 | 3.2 Basic Font Information 92 | (Here is where you would describe the purpose and brief specifications for the font project, and where users can find more detailed documentation. It can also include references to how changes can be contributed back to the Original Version. You may also wish to include a short guide to the design, or a reference to such a document.) 93 | 94 | 3.3 ChangeLog 95 | (This should list both major and minor changes, most recent first. Here are some examples:) 96 | 97 | 7 February 2007 (Pat Johnson) Version 1.3 98 | - Added Greek and Cyrillic glyphs 99 | - Released as "" 100 | 101 | 7 March 2006 (Fred Foobar) Version 1.2 102 | - Tweaked contextual behaviours 103 | - Released as "" 104 | 105 | 1 Feb 2005 (Jane Doe) Version 1.1 106 | - Improved build script performance and verbosity 107 | - Extended the smart code documentation 108 | - Corrected minor typos in the documentation 109 | - Fixed position of combining inverted breve below (U+032F) 110 | - Added OpenType/Graphite smart code for Armenian 111 | - Added Armenian glyphs (U+0531 -> U+0587) 112 | - Released as "" 113 | 114 | 1 Jan 2005 (Joe Smith) Version 1.0 115 | - Initial release of font "" 116 | 117 | 3.4 Acknowledgements 118 | (Here is where contributors can be acknowledged. 119 | 120 | If you make modifications be sure to add your name (N), email (E), web-address (W) and description (D). This list is sorted by last name in alphabetical order.) 121 | 122 | N: Jane Doe 123 | E: jane@university.edu 124 | W: http://art.university.edu/projects/fonts 125 | D: Contributor - Armenian glyphs and code 126 | 127 | N: Fred Foobar 128 | E: fred@foobar.org 129 | W: http://foobar.org 130 | D: Contributor - misc Graphite fixes 131 | 132 | N: Pat Johnson 133 | E: pat@fontstudio.org 134 | W: http://pat.fontstudio.org 135 | D: Designer - Greek & Cyrillic glyphs based on Roman design 136 | 137 | N: Tom Parker 138 | E: tom@company.com 139 | W: http://www.company.com/tom/projects/fonts 140 | D: Engineer - original smart font code 141 | 142 | N: Joe Smith 143 | E: joe@fontstudio.org 144 | W: http://joe.fontstudio.org 145 | D: Designer - original Roman glyphs 146 | 147 | (Original authors can also include information here about their organization.) 148 | 149 | 150 | 4 ABOUT MAKING CONTRIBUTIONS 151 | 152 | 4.1 Why should I contribute my changes back to the original authors? 153 | It would benefit many people if you contributed back to what you've received. Providing your contributions and improvements to the fonts and other components (data files, source code, build scripts, documentation, etc.) could be a tremendous help and would encourage others to contribute as well and 'give back', which means you will have an opportunity to benefit from other people's contributions as well. Sometimes maintaining your own separate version takes more effort than merging back with the original. Be aware that any contributions, however, must be either your own original creation or work that you own, and you may be asked to affirm that clearly when you contribute. 154 | 155 | 4.2 I've made some very nice improvements to the font, will you consider adopting them and putting them into future Original Versions? 156 | Most authors would be very happy to receive such contributions. Keep in mind that it is unlikely that they would want to incorporate major changes that would require additional work on their end. Any contributions would likely need to be made for all the fonts in a family and match the overall design and style. Authors are encouraged to include a guide to the design with the fonts. It would also help to have contributions submitted as patches or clearly marked changes (the use of smart source revision control systems like subversion, svk or bzr is a good idea). Examples of useful contributions are bug fixes, additional glyphs, stylistic alternates (and the smart font code to access them) or improved hinting. 157 | 158 | 4.3 How can I financially support the development of OFL fonts? 159 | It is likely that most authors of OFL fonts would accept financial contributions - contact them for instructions on how to do this. Such contributions would support future development. You can also pay for others to enhance the fonts and contribute the results back to the original authors for inclusion in the Original Version. 160 | 161 | 162 | 5 ABOUT THE LICENSE 163 | 164 | 5.1 I see that this is version 1.1 of the license. Will there be later changes? 165 | Version 1.1 is the first minor revision of the OFL. We are confident that version 1.1 will meet most needs, but are open to future improvements. Any revisions would be for future font releases, and previously existing licenses would remain in effect. No retroactive changes are possible, although the Copyright Holder(s) can re-release the font under a revised OFL. All versions will be available on our web site: http://scripts.sil.org/OFL. 166 | 167 | 5.2 Can I use the SIL Open Font License for my own fonts? 168 | Yes! We heartily encourage anyone to use the OFL to distribute their own original fonts. It is a carefully constructed license that allows great freedom along with enough artistic integrity protection for the work of the authors as well as clear rules for other contributors and those who redistribute the fonts. Some additional information about using the OFL is included at the end of this FAQ. 169 | 170 | 5.3 Does this license restrict the rights of the Copyright Holder(s)? 171 | No. The Copyright Holder(s) still retain(s) all the rights to their creation; they are only releasing a portion of it for use in a specific way. For example, the Copyright Holder(s) may choose to release a 'basic' version of their font under the OFL, but sell a restricted 'enhanced' version. Only the Copyright Holder(s) can do this. 172 | 173 | 5.4 Is the OFL a contract or a license? 174 | The OFL is a license and not a contract and so does not require you to sign it to have legal validity. By using, modifying and redistributing components under the OFL you indicate that you accept the license. 175 | 176 | 5.5 How about translating the license and the FAQ into other languages? 177 | SIL certainly recognises the need for people who are not familiar with English to be able to understand the OFL and this FAQ better in their own language. Making the license very clear and readable is a key goal of the OFL. 178 | 179 | If you are an experienced translator, you are very welcome to help by translating the OFL and its FAQ so that designers and users in your language community can understand the license better. But only the original English version of the license has legal value and has been approved by the community. Translations do not count as legal substitutes and should only serve as a way to explain the original license. SIL - as the author and steward of the license for the community at large - does not approve any translation of the OFL as legally valid because even small translation ambiguities could be abused and create problems. 180 | 181 | We give permission to publish unofficial translations into other languages provided that they comply with the following guidelines: 182 | 183 | - put the following disclaimer in both English and the target language stating clearly that the translation is unofficial: 184 | 185 | "This is an unofficial translation of the SIL Open Font License into $language. It was not published by SIL International, and does not legally state the distribution terms for fonts that use the OFL. A release under the OFL is only valid when using the original English text. 186 | 187 | However, we recognize that this unofficial translation will help users and designers not familiar with English to understand the SIL OFL better and make it easier to use and release font families under this collaborative font design model. We encourage designers who consider releasing their creation under the OFL to read the FAQ in their own language if it is available. 188 | 189 | Please go to http://scripts.sil.org/OFL for the official version of the license and the accompanying FAQ." 190 | 191 | - keep your unofficial translation current and update it at our request if needed, for example if there is any ambiguity which could lead to confusion. 192 | 193 | If you start such a unofficial translation effort of the OFL and its accompanying FAQ please let us know, thank you. 194 | 195 | 196 | 6 ABOUT SIL INTERNATIONAL 197 | 198 | 6.1 Who is SIL International and what does it do? 199 | SIL International is a worldwide faith-based education and development organization (NGO) that studies, documents, and assists in developing the world's lesser-known languages through literacy, linguistics, translation, and other academic disciplines. SIL makes its services available to all without regard to religious belief, political ideology, gender, race, or ethnic background. SIL's members and volunteers share a Christian commitment. 200 | 201 | 6.2 What does this have to do with font licensing? 202 | The ability to read, write, type and publish in one's own language is one of the most critical needs for millions of people around the world. This requires fonts that are widely available and support lesser-known languages. SIL develops - and encourages others to develop - a complete stack of writing systems implementation components available under open licenses. This open stack includes input methods, smart fonts, smart rendering libraries and smart applications. There has been a need for a common open license that is specifically applicable to fonts and related software (a crucial component of this stack) so SIL developed the SIL Open Font License with the help of the FLOSS community. 203 | 204 | 6.3 How can I contact SIL? 205 | Our main web site is: http://www.sil.org/ 206 | Our site about complex scripts is: http://scripts.sil.org/ 207 | Information about this license (including contact email information) is at: http://scripts.sil.org/OFL 208 | 209 | 210 | 7 ABOUT USING THE OFL FOR YOUR ORIGINAL FONTS 211 | 212 | If you want to release your fonts under the OFL, you only need to do the following: 213 | 214 | 7.1 Put your copyright and reserved font names information in the beginning of the main OFL file. 215 | 7.2 Put your copyright and the OFL references in your various font files (such as in the copyright, license and description fields) and in your other components (build scripts, glyph databases, documentation, rendering samples, etc). 216 | 7.3 Write an initial FONTLOG for your font and include it in the release package. 217 | 7.4 Include the OFL in your release package. 218 | 7.5 We also highly recommend you include the relevant practical documentation on the license by putting the OFL-FAQ in your package. 219 | 7.6 If you wish, you can use the OFL Graphics on your web page. 220 | 221 | 222 | 223 | That's all. If you have any more questions please get in touch with us. 224 | 225 | 226 | -------------------------------------------------------------------------------- /src/assets/fonts/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) Authors of original metafont fonts: 2 | Donald Ervin Knuth (cm, concrete fonts) 3 | 1995, 1996, 1997 J"org Knappen, 1990, 1992 Norbert Schwarz (ec fonts) 4 | 1992-2006 A.Khodulev, O.Lapko, A.Berdnikov, V.Volovich (lh fonts) 5 | 1997-2005 Claudio Beccari (cb greek fonts) 6 | 2002 FUKUI Rei (tipa fonts) 7 | 2003-2005 Han The Thanh (Vietnamese fonts) 8 | 1996-2005 Walter Schmidt (cmbright fonts) 9 | 10 | Copyright (C) 2003-2009, Andrey V. Panov (panov@canopus.iacp.dvo.ru), 11 | with Reserved Font Family Name "Computer Modern Unicode fonts". 12 | 13 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 14 | This license is copied below, and is also available with a FAQ at: 15 | http://scripts.sil.org/OFL 16 | 17 | 18 | ----------------------------------------------------------- 19 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 20 | ----------------------------------------------------------- 21 | 22 | PREAMBLE 23 | The goals of the Open Font License (OFL) are to stimulate worldwide 24 | development of collaborative font projects, to support the font creation 25 | efforts of academic and linguistic communities, and to provide a free and 26 | open framework in which fonts may be shared and improved in partnership 27 | with others. 28 | 29 | The OFL allows the licensed fonts to be used, studied, modified and 30 | redistributed freely as long as they are not sold by themselves. The 31 | fonts, including any derivative works, can be bundled, embedded, 32 | redistributed and/or sold with any software provided that any reserved 33 | names are not used by derivative works. The fonts and derivatives, 34 | however, cannot be released under any other type of license. The 35 | requirement for fonts to remain under this license does not apply 36 | to any document created using the fonts or their derivatives. 37 | 38 | DEFINITIONS 39 | "Font Software" refers to the set of files released by the Copyright 40 | Holder(s) under this license and clearly marked as such. This may 41 | include source files, build scripts and documentation. 42 | 43 | "Reserved Font Name" refers to any names specified as such after the 44 | copyright statement(s). 45 | 46 | "Original Version" refers to the collection of Font Software components as 47 | distributed by the Copyright Holder(s). 48 | 49 | "Modified Version" refers to any derivative made by adding to, deleting, 50 | or substituting -- in part or in whole -- any of the components of the 51 | Original Version, by changing formats or by porting the Font Software to a 52 | new environment. 53 | 54 | "Author" refers to any designer, engineer, programmer, technical 55 | writer or other person who contributed to the Font Software. 56 | 57 | PERMISSION & CONDITIONS 58 | Permission is hereby granted, free of charge, to any person obtaining 59 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 60 | redistribute, and sell modified and unmodified copies of the Font 61 | Software, subject to the following conditions: 62 | 63 | 1) Neither the Font Software nor any of its individual components, 64 | in Original or Modified Versions, may be sold by itself. 65 | 66 | 2) Original or Modified Versions of the Font Software may be bundled, 67 | redistributed and/or sold with any software, provided that each copy 68 | contains the above copyright notice and this license. These can be 69 | included either as stand-alone text files, human-readable headers or 70 | in the appropriate machine-readable metadata fields within text or 71 | binary files as long as those fields can be easily viewed by the user. 72 | 73 | 3) No Modified Version of the Font Software may use the Reserved Font 74 | Name(s) unless explicit written permission is granted by the corresponding 75 | Copyright Holder. This restriction only applies to the primary font name as 76 | presented to the users. 77 | 78 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 79 | Software shall not be used to promote, endorse or advertise any 80 | Modified Version, except to acknowledge the contribution(s) of the 81 | Copyright Holder(s) and the Author(s) or with their explicit written 82 | permission. 83 | 84 | 5) The Font Software, modified or unmodified, in part or in whole, 85 | must be distributed entirely under this license, and must not be 86 | distributed under any other license. The requirement for fonts to 87 | remain under this license does not apply to any document created 88 | using the Font Software. 89 | 90 | TERMINATION 91 | This license becomes null and void if any of the above conditions are 92 | not met. 93 | 94 | DISCLAIMER 95 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 96 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 97 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 98 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 99 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 100 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 101 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 102 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 103 | OTHER DEALINGS IN THE FONT SOFTWARE. 104 | -------------------------------------------------------------------------------- /src/assets/fonts/README: -------------------------------------------------------------------------------- 1 | Computer Modern Unicode fonts 2 | 3 | Computer Modern Unicode fonts were converted from metafont sources 4 | using mftrace with autotrace backend and fontforge. Some characters 5 | in several fonts are copied from Blue Sky type 1 fonts released by 6 | AMS. Their main purpose is to create free good quality fonts for use 7 | in X applications supporting many languages. Currently the fonts 8 | contain glyphs from Latin (Metafont ec, tc, vnr), Cyrillic (lh), Greek 9 | (cbgreek when available) code sets and IPA extensions (from tipa). 10 | Other alphabets are also welcome. 11 | 12 | These fonts are distributed under the terms of Open Font License. Some 13 | scripts for font generation are distributed under the terms 14 | of GNU General Public License. 15 | 16 | This font set contains 33 fonts. You can download from homepage the 17 | sfd files and pfb fonts. It is better to use these fonts with 18 | antialiasing enabled. 19 | 20 | Of cause, this version has many unresolved questions and bugs. If you 21 | have found any bug inform me by e-mail. 22 | 23 | Acknowledgements 24 | 25 | Thanks to George Williams the author of the fontforge for his 26 | responsiveness in fixing bugs and adding new features. 27 | 28 | References 29 | 30 | 1. http://lilypond.org/mftrace/ 31 | 2. http://fontforge.sf.net/ 32 | 3. http://canopus.iacp.dvo.ru/~panov/cm-unicode/ (homepage) 33 | 4. ftp://cam.ctan.org/tex-archive/fonts/ec/ (ec and tc fonts) 34 | 5. ftp://cam.ctan.org/tex-archive/fonts/cyrillic/lh (lh fonts) 35 | 6. ftp://cam.ctan.org/tex-archive/fonts/greek/cb (cb greek fonts) 36 | 7. ftp://cam.ctan.org/tex-archive/fonts/tipa (tipa fonts) 37 | 8. ftp://cam.ctan.org/tex-archive/language/vietnamese/vntex/unpacked/fonts/source/vntex/vnr/ (vnr fonts) 38 | 39 | Andrey V. Panov 40 | panov /at/ canopus. iacp. dvo. ru -------------------------------------------------------------------------------- /src/assets/fonts/TODO: -------------------------------------------------------------------------------- 1 | * Some accented Latin characters are missing. 2 | 3 | * Add bitmap built in fonts to opentype ones particularly regular (help from 4 | volunteers is needed). CMUTypewriter-Regular now contains some bitmap fonts. 5 | 6 | * Add anchors 7 | -------------------------------------------------------------------------------- /src/assets/fonts/cmunbbx.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbbx.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbi.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbi.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbl.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbl.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbmo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbmo.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbmr.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbmr.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbso.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbso.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbsr.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbsr.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbtl.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbtl.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbto.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbto.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbx.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbx.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunbxo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunbxo.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunci.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunci.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunit.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunit.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunobi.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunobi.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunobx.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunobx.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunorm.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunorm.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunoti.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunoti.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunrb.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunrb.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunrm.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunrm.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunsi.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunsi.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunsl.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunsl.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunso.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunso.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunss.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunss.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunssdc.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunssdc.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunst.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunst.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunsx.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunsx.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmuntb.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmuntb.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunti.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunti.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmuntt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmuntt.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmuntx.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmuntx.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunui.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunui.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunvi.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunvi.ttf -------------------------------------------------------------------------------- /src/assets/fonts/cmunvt.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joshuanianji/derivative/1c858ba6d4d21b27d34fd2870b905245f155df68/src/assets/fonts/cmunvt.ttf -------------------------------------------------------------------------------- /src/assets/fonts/fonts.scale: -------------------------------------------------------------------------------- 1 | 516 2 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-adobe-standard 3 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-ascii-0 4 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-iso10646-1 5 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-iso8859-1 6 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-iso8859-15 7 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-iso8859-16 8 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-iso8859-2 9 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-iso8859-5 10 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-iso8859-9 11 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-koi8-e 12 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-koi8-r 13 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-koi8-ru 14 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-koi8-u 15 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-koi8-uni 16 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-microsoft-cp1252 17 | cmunbbx.ttf -misc-cmu bright-bold-r-normal--0-0-0-0-p-0-suneu-greek 18 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-adobe-standard 19 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-ascii-0 20 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-iso10646-1 21 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-iso8859-1 22 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-iso8859-15 23 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-iso8859-16 24 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-iso8859-2 25 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-iso8859-5 26 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-iso8859-9 27 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-koi8-e 28 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-koi8-r 29 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-koi8-ru 30 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-koi8-u 31 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-koi8-uni 32 | cmunbi.ttf -misc-cmu serif-bold-i-normal--0-0-0-0-p-0-microsoft-cp1252 33 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-adobe-standard 34 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-ascii-0 35 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-iso10646-1 36 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-iso8859-1 37 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-iso8859-15 38 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-iso8859-16 39 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-iso8859-2 40 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-iso8859-5 41 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-iso8859-9 42 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-koi8-e 43 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-koi8-r 44 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-koi8-ru 45 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-koi8-u 46 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-koi8-uni 47 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-microsoft-cp1252 48 | cmunbl.ttf -misc-cmu serif extra-bold-o-normal--0-0-0-0-p-0-suneu-greek 49 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-adobe-standard 50 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-ascii-0 51 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-iso10646-1 52 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-iso8859-1 53 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-iso8859-15 54 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-iso8859-16 55 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-iso8859-2 56 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-iso8859-5 57 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-iso8859-9 58 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-koi8-e 59 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-koi8-r 60 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-koi8-ru 61 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-koi8-u 62 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-koi8-uni 63 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-microsoft-cp1252 64 | cmunbmo.ttf -misc-cmu bright-medium-o-normal--0-0-0-0-p-0-suneu-greek 65 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-adobe-standard 66 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-ascii-0 67 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-iso10646-1 68 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-iso8859-1 69 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-iso8859-15 70 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-iso8859-16 71 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-iso8859-2 72 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-iso8859-5 73 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-iso8859-9 74 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-koi8-e 75 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-koi8-r 76 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-koi8-ru 77 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-koi8-u 78 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-koi8-uni 79 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-microsoft-cp1252 80 | cmunbmr.ttf -misc-cmu bright-medium-r-normal--0-0-0-0-p-0-suneu-greek 81 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-adobe-standard 82 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-ascii-0 83 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-iso10646-1 84 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-iso8859-1 85 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-iso8859-15 86 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-iso8859-16 87 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-iso8859-2 88 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-iso8859-5 89 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-iso8859-9 90 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-koi8-e 91 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-koi8-r 92 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-koi8-ru 93 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-koi8-u 94 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-koi8-uni 95 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-microsoft-cp1252 96 | cmunbso.ttf -misc-cmu bright-semibold-o-normal--0-0-0-0-p-0-suneu-greek 97 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-adobe-standard 98 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-ascii-0 99 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-iso10646-1 100 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-iso8859-1 101 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-iso8859-15 102 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-iso8859-16 103 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-iso8859-2 104 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-iso8859-5 105 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-iso8859-9 106 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-koi8-e 107 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-koi8-r 108 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-koi8-ru 109 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-koi8-u 110 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-koi8-uni 111 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-microsoft-cp1252 112 | cmunbsr.ttf -misc-cmu bright-semibold-r-normal--0-0-0-0-p-0-suneu-greek 113 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-adobe-standard 114 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-ascii-0 115 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-iso10646-1 116 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-iso8859-1 117 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-iso8859-15 118 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-iso8859-16 119 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-iso8859-2 120 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-iso8859-5 121 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-iso8859-9 122 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-koi8-e 123 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-koi8-r 124 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-koi8-ru 125 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-koi8-u 126 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-koi8-uni 127 | cmunbtl.ttf -misc-cmu typewriter text-extralight-r-normal--0-0-0-0-p-0-microsoft-cp1252 128 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-adobe-standard 129 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-ascii-0 130 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-iso10646-1 131 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-iso8859-1 132 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-iso8859-15 133 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-iso8859-16 134 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-iso8859-2 135 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-iso8859-5 136 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-iso8859-9 137 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-koi8-e 138 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-koi8-r 139 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-koi8-ru 140 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-koi8-u 141 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-koi8-uni 142 | cmunbto.ttf -misc-cmu typewriter text-extralight-o-normal--0-0-0-0-p-0-microsoft-cp1252 143 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-adobe-standard 144 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-ascii-0 145 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-iso10646-1 146 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-iso8859-1 147 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-iso8859-15 148 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-iso8859-16 149 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-iso8859-2 150 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-iso8859-5 151 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-iso8859-9 152 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-koi8-e 153 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-koi8-r 154 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-koi8-ru 155 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-koi8-u 156 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-koi8-uni 157 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-microsoft-cp1252 158 | cmunbx.ttf -misc-cmu serif-bold-r-normal--0-0-0-0-p-0-suneu-greek 159 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-adobe-standard 160 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-ascii-0 161 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-iso10646-1 162 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-iso8859-1 163 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-iso8859-15 164 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-iso8859-16 165 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-iso8859-2 166 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-iso8859-5 167 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-iso8859-9 168 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-koi8-e 169 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-koi8-r 170 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-koi8-ru 171 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-koi8-u 172 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-koi8-uni 173 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-microsoft-cp1252 174 | cmunbxo.ttf -misc-cmu bright-bold-o-normal--0-0-0-0-p-0-suneu-greek 175 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-adobe-standard 176 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-ascii-0 177 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-iso10646-1 178 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-iso8859-1 179 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-iso8859-15 180 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-iso8859-16 181 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-iso8859-2 182 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-iso8859-5 183 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-iso8859-9 184 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-koi8-e 185 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-koi8-r 186 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-koi8-ru 187 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-koi8-u 188 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-koi8-uni 189 | cmunci.ttf -misc-cmu classical serif-medium-i-normal--0-0-0-0-p-0-microsoft-cp1252 190 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-adobe-standard 191 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-ascii-0 192 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-iso10646-1 193 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-iso8859-1 194 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-iso8859-15 195 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-iso8859-16 196 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-iso8859-2 197 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-iso8859-5 198 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-iso8859-9 199 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-koi8-e 200 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-koi8-r 201 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-koi8-ru 202 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-koi8-u 203 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-koi8-uni 204 | cmunit.ttf -misc-cmu typewriter text-medium-i-normal--0-0-0-0-p-0-microsoft-cp1252 205 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-adobe-standard 206 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-ascii-0 207 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-iso10646-1 208 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-iso8859-1 209 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-iso8859-15 210 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-iso8859-16 211 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-iso8859-2 212 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-iso8859-5 213 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-iso8859-9 214 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-koi8-e 215 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-koi8-r 216 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-koi8-ru 217 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-koi8-u 218 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-koi8-uni 219 | cmunobi.ttf -misc-cmu concrete-bold-i-normal--0-0-0-0-p-0-microsoft-cp1252 220 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-adobe-standard 221 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-ascii-0 222 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-iso10646-1 223 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-iso8859-1 224 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-iso8859-15 225 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-iso8859-16 226 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-iso8859-2 227 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-iso8859-5 228 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-iso8859-9 229 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-koi8-e 230 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-koi8-r 231 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-koi8-ru 232 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-koi8-u 233 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-koi8-uni 234 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-microsoft-cp1252 235 | cmunobx.ttf -misc-cmu concrete-bold-r-normal--0-0-0-0-p-0-suneu-greek 236 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-adobe-standard 237 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-ascii-0 238 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-iso10646-1 239 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-iso8859-1 240 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-iso8859-15 241 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-iso8859-16 242 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-iso8859-2 243 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-iso8859-5 244 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-iso8859-9 245 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-koi8-e 246 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-koi8-r 247 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-koi8-ru 248 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-koi8-u 249 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-koi8-uni 250 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-microsoft-cp1252 251 | cmunorm.ttf -misc-cmu concrete-medium-r-normal--0-0-0-0-p-0-suneu-greek 252 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-adobe-standard 253 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-ascii-0 254 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-iso10646-1 255 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-iso8859-1 256 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-iso8859-15 257 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-iso8859-16 258 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-iso8859-2 259 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-iso8859-5 260 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-iso8859-9 261 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-koi8-e 262 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-koi8-r 263 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-koi8-ru 264 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-koi8-u 265 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-koi8-uni 266 | cmunoti.ttf -misc-cmu concrete-medium-i-normal--0-0-0-0-p-0-microsoft-cp1252 267 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-adobe-standard 268 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-ascii-0 269 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-iso10646-1 270 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-iso8859-1 271 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-iso8859-15 272 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-iso8859-16 273 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-iso8859-2 274 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-iso8859-5 275 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-iso8859-9 276 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-koi8-e 277 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-koi8-r 278 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-koi8-ru 279 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-koi8-u 280 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-koi8-uni 281 | cmunrb.ttf -misc-cmu serif extra-bold-r-normal--0-0-0-0-p-0-microsoft-cp1252 282 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-adobe-standard 283 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-ascii-0 284 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso10646-1 285 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-1 286 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-10 287 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-13 288 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-15 289 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-16 290 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-2 291 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-3 292 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-4 293 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-5 294 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-iso8859-9 295 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-koi8-e 296 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-koi8-r 297 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-koi8-ru 298 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-koi8-u 299 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-koi8-uni 300 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-microsoft-cp1252 301 | cmunrm.ttf -misc-cmu serif-medium-r-normal--0-0-0-0-p-0-suneu-greek 302 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-adobe-standard 303 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-ascii-0 304 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-iso10646-1 305 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-iso8859-1 306 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-iso8859-15 307 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-iso8859-16 308 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-iso8859-2 309 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-iso8859-5 310 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-iso8859-9 311 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-koi8-e 312 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-koi8-r 313 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-koi8-ru 314 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-koi8-u 315 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-koi8-uni 316 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-microsoft-cp1252 317 | cmunsi.ttf -misc-cmu sans serif-medium-o-normal--0-0-0-0-p-0-suneu-greek 318 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-adobe-standard 319 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-ascii-0 320 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-iso10646-1 321 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-iso8859-1 322 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-iso8859-15 323 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-iso8859-16 324 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-iso8859-2 325 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-iso8859-5 326 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-iso8859-9 327 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-koi8-e 328 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-koi8-r 329 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-koi8-ru 330 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-koi8-u 331 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-koi8-uni 332 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-microsoft-cp1252 333 | cmunsl.ttf -misc-cmu serif extra-medium-o-normal--0-0-0-0-p-0-suneu-greek 334 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-adobe-standard 335 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-ascii-0 336 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-iso10646-1 337 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-iso8859-1 338 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-iso8859-15 339 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-iso8859-16 340 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-iso8859-2 341 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-iso8859-5 342 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-iso8859-9 343 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-koi8-e 344 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-koi8-r 345 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-koi8-ru 346 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-koi8-u 347 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-koi8-uni 348 | cmunso.ttf -misc-cmu sans serif-bold-o-normal--0-0-0-0-p-0-microsoft-cp1252 349 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-adobe-standard 350 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-ascii-0 351 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-iso10646-1 352 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-iso8859-1 353 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-iso8859-15 354 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-iso8859-16 355 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-iso8859-2 356 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-iso8859-5 357 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-iso8859-9 358 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-koi8-e 359 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-koi8-r 360 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-koi8-ru 361 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-koi8-u 362 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-koi8-uni 363 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-microsoft-cp1252 364 | cmunss.ttf -misc-cmu sans serif-medium-r-normal--0-0-0-0-p-0-suneu-greek 365 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-adobe-standard 366 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-ascii-0 367 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-iso10646-1 368 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-iso8859-1 369 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-iso8859-15 370 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-iso8859-16 371 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-iso8859-2 372 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-iso8859-5 373 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-iso8859-9 374 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-koi8-e 375 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-koi8-r 376 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-koi8-ru 377 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-koi8-u 378 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-koi8-uni 379 | cmunssdc.ttf -misc-cmu sans serif demi condensed-semibold-r-condensed--0-0-0-0-p-0-microsoft-cp1252 380 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-adobe-standard 381 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-ascii-0 382 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-iso10646-1 383 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-iso8859-1 384 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-iso8859-15 385 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-iso8859-16 386 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-iso8859-2 387 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-iso8859-5 388 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-iso8859-9 389 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-koi8-e 390 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-koi8-r 391 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-koi8-ru 392 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-koi8-u 393 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-koi8-uni 394 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-microsoft-cp1252 395 | cmunst.ttf -misc-cmu typewriter text-medium-o-normal--0-0-0-0-m-0-suneu-greek 396 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-adobe-standard 397 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-ascii-0 398 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-iso10646-1 399 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-iso8859-1 400 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-iso8859-15 401 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-iso8859-16 402 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-iso8859-2 403 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-iso8859-5 404 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-iso8859-9 405 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-koi8-e 406 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-koi8-r 407 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-koi8-ru 408 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-koi8-u 409 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-koi8-uni 410 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-microsoft-cp1252 411 | cmunsx.ttf -misc-cmu sans serif-bold-r-normal--0-0-0-0-p-0-suneu-greek 412 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-adobe-standard 413 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-ascii-0 414 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-iso10646-1 415 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-iso8859-1 416 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-iso8859-15 417 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-iso8859-16 418 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-iso8859-2 419 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-iso8859-5 420 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-iso8859-9 421 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-koi8-e 422 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-koi8-r 423 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-koi8-ru 424 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-koi8-u 425 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-koi8-uni 426 | cmuntb.ttf -misc-cmu typewriter text-bold-r-normal--0-0-0-0-p-0-microsoft-cp1252 427 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-adobe-standard 428 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-ascii-0 429 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-iso10646-1 430 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-iso8859-1 431 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-iso8859-15 432 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-iso8859-16 433 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-iso8859-2 434 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-iso8859-5 435 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-iso8859-9 436 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-koi8-e 437 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-koi8-r 438 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-koi8-ru 439 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-koi8-u 440 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-koi8-uni 441 | cmunti.ttf -misc-cmu serif-medium-i-normal--0-0-0-0-p-0-microsoft-cp1252 442 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-adobe-standard 443 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-ascii-0 444 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-iso10646-1 445 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-iso8859-1 446 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-iso8859-15 447 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-iso8859-16 448 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-iso8859-2 449 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-iso8859-5 450 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-iso8859-9 451 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-koi8-e 452 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-koi8-r 453 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-koi8-ru 454 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-koi8-u 455 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-koi8-uni 456 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-microsoft-cp1252 457 | cmuntt.ttf -misc-cmu typewriter text-medium-r-normal--0-0-0-0-m-0-suneu-greek 458 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-adobe-standard 459 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-ascii-0 460 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-iso10646-1 461 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-iso8859-1 462 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-iso8859-15 463 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-iso8859-16 464 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-iso8859-2 465 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-iso8859-5 466 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-iso8859-9 467 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-koi8-e 468 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-koi8-r 469 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-koi8-ru 470 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-koi8-u 471 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-koi8-uni 472 | cmuntx.ttf -misc-cmu typewriter text-bold-i-normal--0-0-0-0-p-0-microsoft-cp1252 473 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-adobe-standard 474 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-ascii-0 475 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-iso10646-1 476 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-iso8859-1 477 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-iso8859-15 478 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-iso8859-16 479 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-iso8859-2 480 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-iso8859-5 481 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-iso8859-9 482 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-koi8-e 483 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-koi8-r 484 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-koi8-ru 485 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-koi8-u 486 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-koi8-uni 487 | cmunui.ttf -misc-cmu serif upright italic-medium-i-normal--0-0-0-0-p-0-microsoft-cp1252 488 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-adobe-standard 489 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-ascii-0 490 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-iso10646-1 491 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-iso8859-1 492 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-iso8859-15 493 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-iso8859-16 494 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-iso8859-2 495 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-iso8859-5 496 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-iso8859-9 497 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-koi8-e 498 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-koi8-r 499 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-koi8-ru 500 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-koi8-u 501 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-koi8-uni 502 | cmunvi.ttf -misc-cmu typewriter text variable width-medium-i-normal--0-0-0-0-p-0-microsoft-cp1252 503 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-adobe-standard 504 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-ascii-0 505 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-iso10646-1 506 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-iso8859-1 507 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-iso8859-15 508 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-iso8859-16 509 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-iso8859-2 510 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-iso8859-5 511 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-iso8859-9 512 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-koi8-e 513 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-koi8-r 514 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-koi8-ru 515 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-koi8-u 516 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-koi8-uni 517 | cmunvt.ttf -misc-cmu typewriter text variable width-medium-r-normal--0-0-0-0-p-0-microsoft-cp1252 518 | -------------------------------------------------------------------------------- /src/assets/main.css: -------------------------------------------------------------------------------- 1 | /* so this file exists just to import a font lol. Would it be easier to use javascript instead? 2 | Literally every internet source tells me to use css's @font-face so... */ 3 | 4 | 5 | @font-face{ 6 | font-family: Computer Modern; 7 | src: url('fonts/cmunrm.ttf') 8 | } 9 | 10 | /* github logo */ 11 | 12 | .github-corner:hover .octo-arm { 13 | animation: octocat-wave 560ms ease-in-out 14 | } 15 | 16 | @keyframes octocat-wave { 17 | 18 | 0%, 19 | 100% { 20 | transform: rotate(0) 21 | } 22 | 23 | 20%, 24 | 60% { 25 | transform: rotate(-25deg) 26 | } 27 | 28 | 40%, 29 | 80% { 30 | transform: rotate(10deg) 31 | } 32 | } 33 | 34 | @media (max-width:500px) { 35 | .github-corner:hover .octo-arm { 36 | animation: none 37 | } 38 | 39 | .github-corner .octo-arm { 40 | animation: octocat-wave 560ms ease-in-out 41 | } 42 | } -------------------------------------------------------------------------------- /src/components/InputMath.js: -------------------------------------------------------------------------------- 1 | export { InputMath } 2 | 3 | var MQ = MathQuill.getInterface(2) 4 | 5 | // custom event for webcomponent to communicate with elm program 6 | 7 | function dispatchEvent(latex) { 8 | var changedLatex = new CustomEvent('changedLatex', { detail: latex }); 9 | document.dispatchEvent(changedLatex) 10 | } 11 | 12 | 13 | // deals with inputting math 14 | 15 | class InputMath extends HTMLElement { 16 | constructor() { 17 | super(); 18 | 19 | console.log("input element initiated"); 20 | } 21 | 22 | connectedCallback() { 23 | 24 | // styles are found in main.css 25 | // I know this breaks the encapsulations and whatnot but shh 26 | this.innerHTML = `` 27 | 28 | var mathField = MQ.MathField(this.querySelector("span"), { 29 | // don't need backslash for words like pi, sqrt, sin, etc. 30 | autoCommands: 'pi sqrt theta phi', 31 | autoOperatorNames: 'sin cos tan csc sec cot ln arcsin arccos arctan arccsc arcsec arccot', 32 | restrictMismatchedBrackets: true, 33 | supSubsRequireOperand: true, 34 | handlers: { 35 | edit: function () { // useful event handlers 36 | console.log(mathField.latex()) 37 | dispatchEvent(mathField.latex()) 38 | } 39 | } 40 | }); 41 | } 42 | 43 | // through ports, elm calls javascript to reset the field and once we get that function we use the mathquill API to do so 44 | clear() { 45 | MQ(this.querySelector("span")).latex("") 46 | } 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/components/StaticMath.js: -------------------------------------------------------------------------------- 1 | var MQ = MathQuill.getInterface(2) 2 | 3 | // deals with displaying math in a static way 4 | 5 | export default class StaticMath extends HTMLElement { 6 | constructor() { 7 | const self = super(); 8 | 9 | self._latexValue = "" 10 | // so mathquill can identify it 11 | self._id = (Math.floor(Math.random() * 10000) + 1).toString(); 12 | console.log("static math initiated - id: " + self._id) 13 | 14 | return self 15 | } 16 | 17 | set latexValue(value) { 18 | 19 | this._latexValue = value 20 | 21 | // delete all children 22 | while (this.firstChild) { 23 | this.removeChild(this.firstChild); 24 | } 25 | 26 | let span = document.createElement("span") 27 | span.id = this._id 28 | span.textContent = this._latexValue 29 | 30 | this.appendChild(span) 31 | MQ.StaticMath(document.getElementById(this._id)) 32 | 33 | // var staticMath = document.getElementById(this._id) 34 | // staticMath.latex(this._latexValue) 35 | } 36 | 37 | get latexValue() { 38 | return this._latexValue 39 | } 40 | 41 | // every time the static math gets initiated i think?? or put on the DOM? 42 | connectedCallback() { 43 | // delete all children 44 | while (this.firstChild) { 45 | this.removeChild(this.firstChild); 46 | } 47 | 48 | let span = document.createElement("span") 49 | span.id = this._id 50 | span.textContent = this._latexValue 51 | 52 | this.appendChild(span) 53 | MQ.StaticMath(document.getElementById(this._id)) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { Elm } from './Main.elm'; 2 | import * as serviceWorker from './serviceWorker'; 3 | import StaticMath from './components/StaticMath'; 4 | import { InputMath } from './components/InputMath' 5 | import './assets/main.css' 6 | 7 | window.customElements.define('mathquill-static', StaticMath); 8 | window.customElements.define('mathquill-input', InputMath); 9 | 10 | var app = Elm.Main.init({ 11 | node: document.getElementById('root') 12 | }); 13 | 14 | app.ports.clear.subscribe(function (nothing) { 15 | document.querySelector("mathquill-input").clear() 16 | }); 17 | 18 | document.addEventListener("changedLatex", function (event) { 19 | app.ports.changedLatex.send(event.detail); // simple API 20 | }) 21 | 22 | 23 | /* NO IDEA WHAT THE CODE BELOW DOES LOL CREATE-ELM-APP MADE THIS FOR ME */ 24 | 25 | // If you want your app to work offline and load faster, you can change 26 | // unregister() to register() below. Note this comes with some pitfalls. 27 | // Learn more about service workers: https://bit.ly/CRA-PWA 28 | serviceWorker.unregister(); 29 | -------------------------------------------------------------------------------- /src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | --------------------------------------------------------------------------------