<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Carlson</title>
    <description>The latest articles on DEV Community by James Carlson (@jxxcarlson).</description>
    <link>https://dev.to/jxxcarlson</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F75298%2Fd004614e-6ed6-4f7f-bbe7-70b9295a391e.png</url>
      <title>DEV Community: James Carlson</title>
      <link>https://dev.to/jxxcarlson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jxxcarlson"/>
    <language>en</language>
    <item>
      <title>Implementing MicroScheme in Elm</title>
      <dc:creator>James Carlson</dc:creator>
      <pubDate>Sun, 12 Mar 2023 13:53:36 +0000</pubDate>
      <link>https://dev.to/jxxcarlson/implementing-microscheme-in-elm-1l1j</link>
      <guid>https://dev.to/jxxcarlson/implementing-microscheme-in-elm-1l1j</guid>
      <description>&lt;p&gt;I'd like to report on a little weekend project, namely to implement an interpreter for a small subset of Scheme using &lt;a href="https://elm-lang.org"&gt;Elm&lt;/a&gt;.  Here is a screenshot of the command-line interface:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U2fPuzcd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://imagedelivery.net/9U-0Y4sEzXlO6BXzTnQnYQ/7bb38caa-c314-48f0-6626-a90140b12c00/public" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U2fPuzcd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://imagedelivery.net/9U-0Y4sEzXlO6BXzTnQnYQ/7bb38caa-c314-48f0-6626-a90140b12c00/public" alt="Scheme Interpreter" width="880" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code (open source, of course!) is on &lt;a href="https://github.com/jxxcarlson/elm-microscheme"&gt;Github&lt;/a&gt; with some&lt;br&gt;
&lt;a href="https://jxxcarlson.github.io/elm-microscheme/about/"&gt;documentation there also&lt;/a&gt;. The code base, as outlined below, is quite small. I intend to keep it that way, since the goal is educational (I am learning a lot).  I'll concentrate on a few core features, e.g., a proper implementation of environments and let-bindings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------------------------------------------------------
File                                               code
--------------------------------------------------------
src/MicroScheme/Eval.elm                            92
src/MicroScheme/Frame.elm                           64
src/MicroScheme/Parser.elm                          56
src/MicroScheme/Interpreter.elm                     43
src/Main.elm                                        41
src/MicroScheme/Environment.elm                     19
src/repl.js                                         19
src/MicroScheme/Expr.elm                            13
src/MicroScheme/Init.elm                            10
-------------------------------------------------------
SUM:                                               357
-------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is more detail in the docs linked above, but perhaps just a few words more.  The current state of the data type for Scheme expressions is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Expr&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Z&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;F&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Str&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Sym&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;L&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;Expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;SF&lt;/span&gt; &lt;span class="kt"&gt;SpecialForm&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;SpecialForm&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Define&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Lambda&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Display&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;If&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I haven't done anything yet with &lt;code&gt;Display&lt;/code&gt; and &lt;code&gt;If&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The module &lt;code&gt;Main&lt;/code&gt; is used to mediate via &lt;a href="https://guide.elm-lang.org/interop/ports.html"&gt;ports&lt;/a&gt; between the interpreter and the Javascript code that runs the command-line interface you saw above in the screenshot. This set-up is very small: just 43 lines of code for &lt;code&gt;Main&lt;/code&gt; and 19 for &lt;code&gt;repl.js&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plans
&lt;/h2&gt;

&lt;p&gt;When the project has matured sufficiently, I will publish a more fully-featured version of the code as an Elm library. I'm also planning to integrate the interpreter into &lt;a href="https://scripta.io"&gt;Scripta.io&lt;/a&gt;, a web publishing platform for technical docs.  Scripta offers three markup languages: MicroLaTeX, XMarkdown, and L0.  The first two are cousins of their official counterparts, while L0 is an experimental effort with syntax inspired by Lisp.&lt;/p&gt;

</description>
      <category>scheme</category>
      <category>elm</category>
      <category>intepreter</category>
    </item>
    <item>
      <title>Towards a Pure Elm Text Editor</title>
      <dc:creator>James Carlson</dc:creator>
      <pubDate>Sat, 13 Feb 2021 17:45:37 +0000</pubDate>
      <link>https://dev.to/jxxcarlson/towards-a-pure-elm-text-editor-3aih</link>
      <guid>https://dev.to/jxxcarlson/towards-a-pure-elm-text-editor-3aih</guid>
      <description>&lt;p&gt;I'd like to report on progress with a text-editor project I've been working on for some time.  It is written purely in &lt;a href="https://elm-lang.org" rel="noopener noreferrer"&gt;Elm&lt;/a&gt;, my favorite language for building web apps. I needed such an editor to build an IDE for another project, &lt;a href="https://minilatex.lamdera.app" rel="noopener noreferrer"&gt;MiniLaTeX&lt;/a&gt;, and had found no other alternatives which suited me. But of course I hope that the editor, when finished, can be of use to others as well. Here is a &lt;a href="https://jxxcarlson.github.io/app/elm-editor2/" rel="noopener noreferrer"&gt;demo&lt;/a&gt; and here is the &lt;a href="https://github.com/jxxcarlson/elm-editor" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The image below gives an idea of what the editor can do.  Below the image I'll discuss features, challenges, and some of the technical details, as well as a bit of the story of how the project came to be. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1pa9208yufpazgohhwkq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1pa9208yufpazgohhwkq.png" alt="announcement-editor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Story
&lt;/h2&gt;

&lt;p&gt;First the story and some acknowledgements.  I had been using the Elm equivalent of text areas for user input, but found a serious problem when the text was modified programmatically - the cursor would jump to the bottom!  Very bad. I needed, for this and other reasons, a real editor.  I tried some drop-in solutions but these did not work out well, so I started dreaming of a pure Elm editor that I could fiddle with at the lowest possible level.  A big task, which I repeatedly put off.&lt;/p&gt;

&lt;p&gt;One day, I chanced upon a prototype by &lt;a href="https://sidneynemzer.github.io/elm-text-editor/" rel="noopener noreferrer"&gt;Sydney Nemzer&lt;/a&gt;. While the demo this link points to might not seem like much, the code is well thought-out, really solid, and beautiful.  To be honest, I had no idea how to solve many basic problems that Nemzer had already solved, e.g., how to interact with the cursor.  Over the next two months, I grew Nemzer's code into a prototype that could do more and integrated it with the MiniLaTeX system. Sadly, as I worked on longer and longer LaTeX documents, the editor slowed down to a point that I was no longer happy with it.  &lt;/p&gt;

&lt;p&gt;About that time I heard a &lt;a href="https://www.implementingelm.com/102/" rel="noopener noreferrer"&gt;podcast with Martin Janiczek&lt;/a&gt;, where, among other things, he discussed what turned out to be an earlier prototype that Nemzer had based his work on.  The difference: in Janiczek's version, the fundamental data structure was an array of lines, whereas in Nemzer's it was a single string.  The latter is in many ways easier to work with, but the former is more efficient.  Over the course of a couple of weeks, I rewrote the code to use an array. Lots of primitives working with text areas to replace basic string operations. Finally: much better performance!&lt;/p&gt;

&lt;h2&gt;
  
  
  Another challenge
&lt;/h2&gt;

&lt;p&gt;Well, the long file story was not over.  Web browsers slow to a crawl when the number of DOM nodes grows too large, and of course that would be the case if the editor loads the entire text of a large document into the DOM so that it can be scrolled in an unfettered way.  &lt;/p&gt;

&lt;p&gt;I decided to address the problem head-on by downloading a copy of Darwin's &lt;em&gt;Origin of the Species&lt;/em&gt;, weighing in at more than 15,000 lines. This was to be my test file. The strategy would be to maintain a "window" into the full array of lines that was characterized by an offset and a "height," - the number of lines in the window.  I've been using 600 lines for the window, with the editor displaying just 33 lines. We'll call the 33-line visible display the &lt;em&gt;viewport&lt;/em&gt;. When the upper or lower edge of the viewport gets too close to the upper or lower edge of the window, the offset is repositioned so that the viewport is well inside it. This solution worked really well, and was quite snappy when editing &lt;em&gt;The Origin of the Species&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Repositioning the viewport and window was slightly tricky - it should be unnoticeable to the user. Before solving that problem, of course, I had to redo the cursor-management code so as to take into account the offset. &lt;/p&gt;

&lt;h2&gt;
  
  
  On to new features!
&lt;/h2&gt;

&lt;p&gt;This work done, I was finally ready to do what I had long wanted to do: implement LaTeX command completion.  The idea is this.  In LaTeX there are many constructions like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$$
\int x^n dx = \frac{1}{n+1}
$$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\begin{theorem}
There are infinitely many primes.
\end{theorem}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are problematic in an app like &lt;a href="https://minilatex.lamdera.app" rel="noopener noreferrer"&gt;minilatex.lamdera.app&lt;/a&gt; which updates the rendered LaTeX every 300 milliseconds or so. The reason is that if the user types &lt;code&gt;\begin{theorem}&lt;/code&gt; without the closing &lt;code&gt;\end{theorem}&lt;/code&gt;, the source text is in a particularly obnoxious error state that can extend to the end of the document.  Ugh! One solution is have a keystroke sequence like &lt;code&gt;ESC th ESC&lt;/code&gt; that inserts the text below, placing the cursor just before the XXX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\begin{theorem}
XXX
\end{theorem}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, the user can be in a mostly error-free state at all times.  (By "mostly", I mean avoiding really bad errors that extend over huge parts of the document because of unmatched begin-end pairs and the like).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Developer Experience
&lt;/h2&gt;

&lt;p&gt;In word, it was a good.  Elm's type system helps me to think about what needs to be done and to translate ideas into code in a friction-free way.  I've also found that it helps when I come back to a project after a long break, as I did several times with this one.  In a very short time, I'm able to get the code "back into my head" and start forging ahead.&lt;/p&gt;

&lt;p&gt;The fact that Elm is is compiled language is a huge advantage. A problem I faced in my previous life as a web developer was extreme FOR anxiety: Fear Of Refactoring: don't even think about the code, much less touch it: it might break! With Elm, by contrast, refactoring is a pleasure. Many times now I've changed a fundamental data structure deep in the core of the code, followed the compiler messages, and come out the other end an hour or two or three later with a fully functioning app - and the confidence that it is indeed free of lurking runtime bugs.&lt;/p&gt;

&lt;p&gt;One last comment.  Some years ago, I watched Rich Hickey's talk, &lt;a href="https://www.youtube.com/watch?v=f84n5oFoZBc" rel="noopener noreferrer"&gt;Hammock-driven development&lt;/a&gt;.  It is both entertaining and insightful.  I used this methodology in the project several times with good results. Highly recommended!&lt;/p&gt;

&lt;h2&gt;
  
  
  Further technical notes
&lt;/h2&gt;

&lt;p&gt;The app posted &lt;a href="https://jxxcarlson.github.io/app/elm-editor2/" rel="noopener noreferrer"&gt;here&lt;/a&gt; was compiled using Matt Griffith's &lt;a href="https://discourse.elm-lang.org/t/announcing/6192" rel="noopener noreferrer"&gt;elm-optimize-level-2&lt;/a&gt;, then minified using &lt;code&gt;uglify-js&lt;/code&gt;, resulting in a 307kb &lt;code&gt;js&lt;/code&gt; file.  This &lt;code&gt;js&lt;/code&gt; file includes code for the editor, the MiniLaTeX-to-Html compiler, and a custom Markdown compiler, all written in Elm.  Using &lt;code&gt;elm make --optimize&lt;/code&gt;, the &lt;code&gt;js&lt;/code&gt; file is slightly larger: 319kb. &lt;/p&gt;

&lt;p&gt;The small asset size is due to the fact that &lt;code&gt;elm make --optimize&lt;/code&gt; performs dead-code elimination on a per-function basis.  If a module consists of one hundred functions, and only three (with their dependencies) are called by the code, then only those three survive compilation to Javascript.&lt;/p&gt;

&lt;p&gt;I'll have to run some benchmarks on large LaTeX files to see to what extent &lt;code&gt;elm-optimize-level-2&lt;/code&gt; speeds things up. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tooling
&lt;/h2&gt;

&lt;p&gt;I've been using Umberto Pepato's &lt;a href="https://dev.to/umbo/velociraptor-an-npm-style-script-runner-for-deno-26"&gt;Velociraptor&lt;/a&gt; for running all my development scripts ever since I learned about it on dev.to.  Simple, light-weight, and perfect for the job.  I love it!  Velociraptor is written in Deno.&lt;/p&gt;

</description>
      <category>latex</category>
      <category>elm</category>
      <category>editor</category>
    </item>
    <item>
      <title>Making an Elm Desktop app with Tauri</title>
      <dc:creator>James Carlson</dc:creator>
      <pubDate>Mon, 15 Jun 2020 09:40:40 +0000</pubDate>
      <link>https://dev.to/jxxcarlson/making-an-elm-desktop-app-with-tauri-3n3i</link>
      <guid>https://dev.to/jxxcarlson/making-an-elm-desktop-app-with-tauri-3n3i</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Th61iJ_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://noteimages.s3.amazonaws.com/jxxcarlson/tuari-app.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Th61iJ_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://noteimages.s3.amazonaws.com/jxxcarlson/tuari-app.png" alt="app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd like to report briefly on my experience using Tauri to make a desktop version of an Elm app, provide it with access to a designated directory on disk, and package it for distribution.  &lt;/p&gt;

&lt;p&gt;In two words: awesome &amp;amp; amazing!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up for dev
&lt;/h2&gt;

&lt;p&gt;Time from starting to read the docs to bringing up the app with &lt;code&gt;npx tauri dev&lt;/code&gt; was about 30 minutes. Had some very quick and accurate help on Discord from the dev team. I expect a certain amount of frustration and head-banging when trying something new.  This was pleasant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the app in dev
&lt;/h2&gt;

&lt;p&gt;With one exception, the app worked as it had before running under Elm-live.  The exception was some copy-paste functionality that uses ports and the &lt;code&gt;navigator&lt;/code&gt; API.  This gave me one of those fun &lt;code&gt;undefined&lt;/code&gt; error messages in the console. (Right click on something in the app to bring up dev tools).  I'll have to learn to use the Tauri API's.&lt;/p&gt;

&lt;p&gt;Impressively, the other port-JS interop worked flawlessly, including (for me), the crucial &lt;code&gt;MathJax.js&lt;/code&gt; library which renders LaTeX-style math formulas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bundling the app
&lt;/h2&gt;

&lt;p&gt;A snap.  I compiled and minified &lt;code&gt;Main.elm&lt;/code&gt; as &lt;code&gt;Main.js&lt;/code&gt; and copied it into &lt;code&gt;./dist&lt;/code&gt;.  Ditto for &lt;code&gt;index.html&lt;/code&gt; which references &lt;code&gt;Main.js&lt;/code&gt; as well as one Css file and several JS files in &lt;code&gt;./assets&lt;/code&gt;.  The directory &lt;code&gt;./assets&lt;/code&gt; was also copied into &lt;code&gt;./dist&lt;/code&gt;.  With the files in place, I ran &lt;code&gt;npx tauri bundle&lt;/code&gt;.  After a while, the results were deposited as listed below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree -L 2 src-tauri/target/release/bundle/
src-tauri/target/release/bundle/
├── dmg
│   ├── app.dmg
│   ├── bundle_dmg.sh
│   └── support
└── osx
    └── muEdit.app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you say “show package contents” for the app in osx, you find the file Contents/MacOs/app which weighs 4.9 MB. This is the executable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the bundled app
&lt;/h2&gt;

&lt;p&gt;Well, it just worked!: access to local and remote web servers, operation of the pure Elm text editor, compiling and rendering Markdown and (Mini)LaTeX, to HTML, rendering of math formulas, rendering of SVG images presented as strings, etc.  And all quite snappy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;I need to learn how to use the Tauri JS API to give access to the file system.  The idea is for authors to be able to store all the work locally on disk as well as (if they wish) on a remote server.  Folks like to have ownership of what they create.  This may be a bit tricky: for Elm JS interop, I have to go through ports, referencing a file &lt;code&gt;outside.js&lt;/code&gt;.  But to get the file API, have to say &lt;code&gt;const fs = require ...&lt;/code&gt;.  And it seems that that means some contortions with &lt;code&gt;browserify&lt;/code&gt;.  But it looks doable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Tauri looks like a &lt;em&gt;very&lt;/em&gt; promising way to bundle web apps.  I'm looking forward to working with it more.  &lt;/p&gt;

&lt;h2&gt;
  
  
  PS
&lt;/h2&gt;

&lt;p&gt;If you have worked with both Elm and Tauri, please ping me here, on the Elm Slack or using gmail.  Username is jxxcarlson everywhere. Would love to discuss this.  Am also interested in Rust bindings.&lt;/p&gt;

&lt;h2&gt;
  
  
  PPS (Two days later)
&lt;/h2&gt;

&lt;p&gt;It is now two days since starting my experiment with Tauri.  I've implemented all the CRUD operations needed to persist documents to disk in a designated directory: create, list, read, update, and delete.  These operations are carried out by one Elm module,&lt;code&gt;Outside&lt;/code&gt;, that talks to one JS file, &lt;code&gt;outside.js&lt;/code&gt; via a single pair of ports.  (Murphie Randall's approach).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So yes, we can indeed use Tauri to build Elm desktop apps with the hard disk used to preserve state.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;I would like to thank all of those who commented on an &lt;a href="https://discourse.elm-lang.org/t/making-a-desktop-app-with-elm-deno-velociraptor-and-now-tauri/5917/32"&gt;article I posted on Discourse&lt;/a&gt; on what turned out to be a poor initial strategy (using a localhost server). The comments on the post lead me to Tauri.&lt;/p&gt;

&lt;p&gt;I would also like to thank the members of &lt;a href="https://tauri.studio/"&gt;Tauri&lt;/a&gt; core team — &lt;a class="comment-mentioned-user" href="https://dev.to/nothingismagick"&gt;@nothingismagick&lt;/a&gt;
, &lt;a class="comment-mentioned-user" href="https://dev.to/laegel"&gt;@laegel&lt;/a&gt;
, and @lucasfernog — who generously gave of their time to help solve several problems and points of confusion on my part. Their help made it possible to make fast progress.&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/jxxcarlson/elm-editor/tree/master/demo"&gt;Github repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elm</category>
      <category>elmlang</category>
      <category>tauri</category>
    </item>
    <item>
      <title>Why Elm is the right tool to build MiniLatex</title>
      <dc:creator>James Carlson</dc:creator>
      <pubDate>Tue, 28 Aug 2018 01:48:44 +0000</pubDate>
      <link>https://dev.to/jxxcarlson/why-elm-is-the-right-tool-to-build-minilatex-3b87</link>
      <guid>https://dev.to/jxxcarlson/why-elm-is-the-right-tool-to-build-minilatex-3b87</guid>
      <description>&lt;p&gt;LaTeX is the &lt;em&gt;de facto&lt;/em&gt; markup language for writing technical articles with lots of mathematics in them — research articles, class notes, etc. In this post, I will describe how I used Elm to build a live-rendering web app for LaTeX.  You can try out the demo at &lt;a href="https://jxxcarlson.github.io/app/miniLatexLive/index.html" rel="noopener noreferrer"&gt;MiniLatex Live&lt;/a&gt;, which is pictured below. (This article continues below the image)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnq1bvv089o81m71u7a5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnq1bvv089o81m71u7a5.png" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About LaTeX
&lt;/h2&gt;

&lt;p&gt;A few words about LaTeX. The infrastructure for rendering it in print via PDF is excellent and well-established.  For the web, there is a partial solution.  A LaTeX document is made of two kinds of text — math mode and text mode.  The formulas are in math mode, and the rest — section headings, tables of contents, cross references, theorem environments, macros, plain old prose, etc. — are in text mode.  Mathjax or KaTeX can render the math mode material, but to my knowledge there has been to date no way of &lt;em&gt;live&lt;/em&gt; rendering all of LaTeX. That is what MiniLatex, a 3k loc Elm library does.  In a word, it uses a custom parser based on the &lt;code&gt;elm/parser&lt;/code&gt; library to transform LaTeX source text into an abstract syntax tree (AST).  Once one has an AST in hand, writing a renderer for the text mode material is fairly straightforward, with the math mode material delegated to MathJax.  &lt;/p&gt;

&lt;h2&gt;
  
  
  The Beginning
&lt;/h2&gt;

&lt;p&gt;I began working on the MiniLatex project just a little over a year ago, shortly after the Elm Europe conference in June 2017.  That was when I realized that &lt;code&gt;elm/parser&lt;/code&gt; may have the mojo to parse LaTeX.  Happily, the parser lived in a framework for building Elm apps, so the combination was perfectly suited to my needs. Even now, a year later, the parser is only 300 lines of code in  3K loc library. But writing it was a real challenge for me: (a) I am a mathematician, not a computer scientist, and I knew only a little about parsing; (b) normally one begins with a grammar, then writes the parser — but there is no written grammar for LaTeX; (c) therefore, one has to reverse-engineer both a grammar and parser; (d) it turns out that any  grammar for any adequate subset of LaTeX must be context-sensitive; (e) therefore the standared parser-generator tools cannot be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Obstacles
&lt;/h2&gt;

&lt;p&gt;Despite these obstacles, of which I was (fortunately) for the most part only dimly aware, I began work on the parser. The &lt;code&gt;elm/parser&lt;/code&gt; library is a parser-combinator library.  It gives tools for building up a parser in a sensible way from little pieces.  This is ideal for experimentation, which is what I had to do the absence of a grammar.  The first step was to define an Elm type for the AST.  Here it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type LatexExpression
    = LXString String
    | Comment String
    | Item LatexExpression
    | InlineMath String
    | DisplayMath String
    | SMacro String (List LatexExpression) (List LatexExpression) LatexExpression 
    | Macro String (List LatexExpression) (List LatexExpression) 
    | Environment String (List LatexExpression) LatexExpression
    | LatexList (List LatexExpression)
    | LXError (List DeadEnd)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just 11 lines of code that governs a 300 line parser which is the heart of a 3000 line library.  I did not write all 11 lines in one go.  I wrote a few lines, tried to build a parser that would handle them, and then iterated. &lt;/p&gt;

&lt;h2&gt;
  
  
  Slow going at first
&lt;/h2&gt;

&lt;p&gt;The going was quite slow at first. Evan Czaplicki had brought &lt;code&gt;elm/parser&lt;/code&gt;, parser combinator library. Although I had read a little about parser combinators, I had never used them. Thankfully, I had much generous assistance from community on the Elm Slack, and  Ilias van Peer, who hangs out there frequently, helped me over many, many rough spots.  (Thankyou Ilias!)  Bye and bye I got the hang of it.&lt;/p&gt;

&lt;p&gt;Over the next few months, things came together, and by the time of the of the Elm Conf in September of 2017, I had a decent working prototype.  But there was a problem.  The parser was too slow!  I could easily take  15 seconds to parse a few pages of text.  I was chatting back and forth with Ilias about this, who discovered the bottleneck was — characters were boxed into a JS object (as I understand it). The problem was likely to be fixed in the 0.19 version of the compiler, so in the meantime, using another of Ilias' suggestions, implementing a diffing strategy that made incremental parse-render operations (after the initial, full-document parse) &lt;strong&gt;very&lt;/strong&gt; fast.  &lt;/p&gt;

&lt;h2&gt;
  
  
  0.19!!!
&lt;/h2&gt;

&lt;p&gt;All of these efforts came together when the alpha of 0.19 came out.  The &lt;code&gt;elm/parser&lt;/code&gt; library had been rewritten and as a result the MiniLatex parser (which also had to be rewritten) was incredibly fast. That speedup, combined with the diffing strategy, made live-rendering of LaTeX documents a reality.  I hadn't thought that this would be possible, but yes, it was!&lt;/p&gt;

&lt;h2&gt;
  
  
  Comments
&lt;/h2&gt;

&lt;p&gt;Elm was my first experience with a typed functional language.  It took me a while to understand the type system well, and also to appreciate its power. I now realize that this is one of Elm's great strengths. Of course, we as developers experience it in our daily work when we embark on an extreme refactoring operation and come out of the battle an hour or two later with everything working. (Thank you, compiler, for your helpful messages!) But in this project, the type system played a central role. The real beginning of MiniLatex was the moment when I wrote down a first version of the &lt;code&gt;LatexExpression&lt;/code&gt; type.  The code for the parser grew out of this type definition, and it has played a guiding role throughout.&lt;/p&gt;

&lt;p&gt;The success of the MiniLatex project was made possible by the generous help of the community on the Elm Slack, and by Ilias in particular. I would also like to thank Evan Czaplicki and Luke Westby, who helped me at some critical points in the transition from 0.18 to 0.19.  It has been a joy to work with Elm, and I would like to give  a big shout out of appreciation to Evan and the core Team.  Bravo! What a fantastic thing you have made!!&lt;/p&gt;

&lt;h3&gt;
  
  
  Caveat
&lt;/h3&gt;

&lt;p&gt;MiniLatex is two things: a proper subset of LaTeX and a parser-render for that subset.  The subset, which is of course subject to expansion as time and energy permit, is nonetheless adequate to write some pretty &lt;a href="https://knode.io/427" rel="noopener noreferrer"&gt;heavy lecture notes&lt;/a&gt;. MiniLatex documents can also be exported and run through standard machines like &lt;code&gt;pdflatex&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Note
&lt;/h3&gt;

&lt;p&gt;MiniLatex is embedded in an app at &lt;a href="https://knode.io" rel="noopener noreferrer"&gt;knode.io&lt;/a&gt; which provides a live editing environment, a searchable repository where the documents you write a are stored, an image uploader, and a searchable image catalogue. &lt;/p&gt;

</description>
      <category>elm</category>
      <category>latex</category>
      <category>minilatex</category>
      <category>parsing</category>
    </item>
  </channel>
</rss>
