<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="https://orsn.io/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <atom:link href="https://orsn.io/rss.xml" rel="self" type="application/rss+xml"/>
    <title>Orsn v2 Updates</title>
    <link>https://orsn.io/v2/</link>
    <description>Updates and progress on Orsn v2 development</description>
    <language>en-US</language>
    <pubDate>Tue, 16 Jun 2026 09:14:15 GMT</pubDate>
    <lastBuildDate>Tue, 16 Jun 2026 09:14:19 GMT</lastBuildDate>
    <generator>@vuepress/plugin-feed</generator>
    <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
    <copyright>2026 Orsn</copyright>
    <item>
      <title>New content types for research</title>
      <link>https://orsn.io/v2/2026-06-15.html</link>
      <guid>https://orsn.io/v2/2026-06-15.html</guid>
      <source url="https://orsn.io/rss.xml">New content types for research</source>
      <description>Content blocks and revisions</description>
      <pubDate>Mon, 15 Jun 2026 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>15th June 2026</h1>
<h3>New content types for research</h3>
<p>I've been lucky enough to have some time over the last few months to make a lot more progress with Open Research Notebook version 2.</p>
<p>One area I've been focusing on is the basic text editing experience, and supporting the kinds of content which are particularly useful for research.</p>
<p>The editor now supports:</p>
<ul>
<li><strong>code blocks</strong> with full syntax highlighting and autocompletion for many programming languages;</li>
<li><strong>table</strong> creation and editing; and</li>
<li><strong>mathematical notation</strong></li>
</ul>
<p>Under the hood, all text is still saved in the Markdown format. So the features I've added are those supported by the Markdown format, in particular the GitHub flavour of Markdown, which has some useful non-standard features. Some of these features can be quite fussy to work with in raw Markdown format, for example table creation. With that in mind, I have used a text editor which is flexible enough to embed dynamic components, such as a table widget with drag handles for creating new rows and columns. These dynamic widgets make editing and viewing data easier and more intuitive, even though the ultimate output is still the same – plain text.</p>
<p>As the video below shows, a popup menu allows you to insert tables, codeblocks, and so on: but there are also typing shortcuts which will achieve the same thing. For example, typing <code>$$</code> at the start of a new line, followed by the enter key, will automatically insert a LaTeX mathematical notation block, opened in editing mode.</p>
<h3>Improved revisions mode</h3>
<p>I've also updated the revisions mode, so that the 'diff' view, which shows the changes between revision snapshots, is more sophisticated: it shows line numbers and highlights lines removed, added or edited, with colour coding.</p>
<video controls="" style="width: 100%; max-width: 800px;"> 
    <source src="/videos/OrsnInsertContent1080.mp4" type="video/mp4">
    Your browser does not support the video tag.
</video>
<h3>Contact</h3>
<p>Find me on the fediverse (Mastodon) <strong>@Lemmy@post.lurk.org</strong>, or send an email to: <strong>info [at] orsn.io</strong></p>
]]></content:encoded>
    </item>
    <item>
      <title>Revising the Revisions</title>
      <link>https://orsn.io/v2/2026-04-20.html</link>
      <guid>https://orsn.io/v2/2026-04-20.html</guid>
      <source url="https://orsn.io/rss.xml">Revising the Revisions</source>
      <description>A more robust versioning system</description>
      <pubDate>Mon, 20 Apr 2026 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>20th April 2026</h1>
<h3>Revising the Revisions</h3>
<p>Working on the basic text editing functionality in Orsn, I found that before I could work on text block features (tables, etc.) I had to update something more fundamental: the Revisions system for keeping track of changes to Cards and Pages.</p>
<p>Part of the philosophy of Orsn as a tool for documenting research is to allow the writer to 'share their workings' if they so desire, in the spirit of open scholarship and transparency; viewing the history and evolution of a document might allow readers to make a more informed judgement of the researcher's process and assumptions.<br>
Of course there is no requirement in Orsn to publish work or share revision drafts, and having access to revision snapshots is also extremely practical for writing of any kind – it allows for freedom in exploring one path in depth, knowing that it is always possible to retrace one's steps if one arrives at a dead end. Sometimes it's necessary to go back and take a different fork in the road.<br>
This is a wonderful feature of <a href="https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell" target="_blank" rel="noopener noreferrer">branching</a> in <a href="https://git-scm.com/" target="_blank" rel="noopener noreferrer">git</a>. I have often thought about how this workflow might be translated into non-programming scenarios. That was a fundamental reason why I chose to use Markdown as the text format for Orsn. Plain text allows for this kind of tracking.</p>
<h4>Version control and publishing</h4>
<p>My conception for Revisions in Orsn is closely tied to git. While Orsn stores its data in a database, rather than flat text files, it will be possible to serialise its data (export them) to a series of Markdown files which will be exportable as a git repository. Conversely, it will also be possible to import Projects from git repos and deserialise them (import them) for viewing and further editing.<br>
In this scenario, the Revisions in Orsn function as git <a href="https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository" target="_blank" rel="noopener noreferrer">commits</a>, or snapshots, so that key changes can be documented, but without the learning curve and the tooling required for working with git. When a Project is exported and published as a git repository, it becomes available in that format for anyone familiar with version control and its more sophisticated options; and it can become a site for collaboration, if that's useful.</p>
<p>So, in short, every Revision in Orsn becomes a git commit in the exported git repository. (For the moment there is no equivalent of branches in Orsn. This may arrive at some point in future. We walk, or at least toddle, before we can run.)</p>
<h4>Out with the old</h4>
<p>In Orsn v1, the revision system stored changes as a series of patches: that is, it only stored the parts of a text document which had changed since last time. That is a space-spacing approach, but it introduces a long chain of dependencies.<br>
Picture this: a document is revised 5 times. The original document is stored in full, along with the text changes made in each subsequent revision. To view the document at, say, revision 4, we have to load the original document, apply the patch changes of revision 1, then to the resultant updated document, apply the patch changes of revision 2. And so on.  Until we get to the desired revision, number 4.</p>
<p>You can imagine that in a long chain of revisions, this introduces a lot of vulnerability to errors. If there is an issue in applying just one of the patches, the rest in the chain will fail, and it won't be possible to construct the document.</p>
<p>In the new v2 revision system, I have accepted the compromise of slightly greater storage requirements in exchange for greater reliability (plain text doesn't use up too much space, so this is reasonable). In the new system, a full snapshot of a given change is captured, making its restoration <strong>much</strong> more robust. It's still possible to calculate and show the differences between a revision and its predecessor, and I have included that option. With the new snapshots, changes to title and tags are also captured, and we have flexibility to track other properties if they are introduced. This new setup feels much more solid and dependable than the 'cumulative patch' system of Orsn v1.</p>
<video controls="" style="width: 100%; max-width: 800px;"> 
    <source src="/videos/OrsnRevisions1080.mp4" type="video/mp4">
    Your browser does not support the video tag.
</video>
<h3>Contact</h3>
<p>Find me on the fediverse (Mastodon) <strong>@Lemmy@post.lurk.org</strong>, or send an email to: <strong>info [at] orsn.io</strong></p>
]]></content:encoded>
    </item>
    <item>
      <title>The Big Clean Up</title>
      <link>https://orsn.io/v2/2026-04-13.html</link>
      <guid>https://orsn.io/v2/2026-04-13.html</guid>
      <source url="https://orsn.io/rss.xml">The Big Clean Up</source>
      <description>Tidying and documenting the code base</description>
      <pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>13th April 2026</h1>
<h3>The Big Clean Up</h3>
<p>I had a chance to return to Orsn last week. It's been a while, so I did a Big Clean Up, sorting all methods and import statements alphabetically, and labelling my Vue component sections consistently. Although I've been using IntelliJ for some years I haven't used the Bookmarks feature in the past. It's very useful, in conjunction with the minimap feature ('CodeGlance Pro' plugin), which gives a graphical overview of a given file, and includes text links to bookmarked lines.</p>
<p>This was also a good opportunity, as I was refamiliarising myself with some of the code, to document tricky features where the workings were not immediately obvious, in particular component structures. Bringing a fresh eye also prompted some refactoring of variable and function names for clarity.
As a consequence I was able to fix some issues with my implementation of ProseMirror inline menus.</p>
<p>My aim is to include jsdoc documentation in the code base for important functionality, but for my own reference I've also been creating separate descriptive Markdown files where I visualise the component structures of key pages, and detail where the responsibilities for data flow and updates lie. This is the kind of thing certain efficient programmers do at the start of their development cycle. Doing it retrospectively will have to suffice in this case. For me it is now essential as the codebase is large and there is a tendency to solve problems and move on, so the detail of implementation can become muddied without careful write-ups.</p>
<p>I started out hoping to use <a href="https://mermaid.js.org/" target="_blank" rel="noopener noreferrer">Mermaid</a> for creating Markdown visualisations, but it turns out that creating simple wireframe diagrams with blocks and nested blocks, is not yet one of its strengths. After wrestling with some buggy rendering of simple panel layouts, I gave up on it and looked for alternatives. I was pleased to find an IntelliJ plugin which opens the <a href="https://www.drawio.com/" target="_blank" rel="noopener noreferrer">drawio</a> editor within the IDE, so I was able to draw and edit my simple diagrams directly as SVG files, and embed them in my MD documentation.</p>
<p>I'm still thinking about supporting Mermaid diagrams in Orsn, however: it does seem effective for other use cases.</p>
<h3>Contact</h3>
<p>Find me on the fediverse (Mastodon) <strong>@Lemmy@post.lurk.org</strong>, or send an email to: <strong>info [at] orsn.io</strong></p>
]]></content:encoded>
    </item>
    <item>
      <title>Orsn development diary</title>
      <link>https://orsn.io/v2/</link>
      <guid>https://orsn.io/v2/</guid>
      <source url="https://orsn.io/rss.xml">Orsn development diary</source>
      <description>Development updates</description>
      <pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>Orsn version 2 – development diary</h1>
]]></content:encoded>
    </item>
    <item>
      <title>Markdown editor updates</title>
      <link>https://orsn.io/v2/2025-11-12.html</link>
      <guid>https://orsn.io/v2/2025-11-12.html</guid>
      <source url="https://orsn.io/rss.xml">Markdown editor updates</source>
      <description>More Progress with ProseMirror.</description>
      <pubDate>Wed, 12 Nov 2025 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>12th November 2025</h1>
<h3>Markdown editor updates</h3>
<p>A preview of some of the new text editing features in Orsn v2.<br>
The new default editor is now a WYSIWYG text editor with various keyboard-driven menu options.<br>
Under the hood the editor creates plain text markdown, but it's easy to use if you're not familiar with the markdown format.
It's even possible to enter markdown syntax directly into the WYSIWYG editor: elements like headings and checkboxes are rendered automatically.</p>
<p>There is also a markdown mode, with optional splitscreen preview, for editing in markdown format directly.</p>
<p>Still a work in progress and lots more to come!!</p>
<video controls="" style="width: 100%; max-width: 800px;"> 
    <source src="/videos/OrsnMarkdownEditing1080.mp4" type="video/mp4">
    Your browser does not support the video tag.
</video>
<h3>Contact</h3>
<p>Find me on the fediverse (Mastodon) <strong>@Lemmy@post.lurk.org</strong>, or send an email to: <strong>info [at] orsn.io</strong></p>
]]></content:encoded>
    </item>
    <item>
      <title>Moving. Forwards. Slowly.</title>
      <link>https://orsn.io/v2/2025-07-11.html</link>
      <guid>https://orsn.io/v2/2025-07-11.html</guid>
      <source url="https://orsn.io/rss.xml">Moving. Forwards. Slowly.</source>
      <description>Progress with ProseMirror.</description>
      <pubDate>Fri, 11 Jul 2025 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>11th July 2025</h1>
<h3>Moving. Forwards. Slowly.</h3>
<p>As a result of my focusing on work which I actually get <em>paid</em> to do, Orsn development has been slower in recent months: nevertheless it has been edging forwards.</p>
<p>I've been working on inline toolbars and menus in the ProseMirror text editor, which I'm integrating into version 2 of Orsn. I started with a 'mentions' inline menu for creating previewable links to other content in the app. It's triggered by the '@' key:</p>
<p><img src="/images/development_diary/insert_mentions2.gif" alt=""></p>
<br>
<br>
<br>
<br>
<p>I then moved on to menus for text formatting and inserting other kinds of content.</p>
<p><img src="/images/development_diary/inline_toolbars.gif" alt=""></p>
<br>
<br>
<br>
<br>
<p>Creating inline toolbars and menus for the ProseMirror text editor has been time-consuming, and somewhat complicated, mainly because of the need to integrate ProseMirror into the Javascript Vue framework which I'm using to build Orsn. ProseMirror is designed to interact with the browser's document object model (DOM) directly, adding and removing interface elements as required. Vue, on the other hand, allows for a certain level of abstraction which make it easier to update sections of page content dynamically, keeping visualised content in sync with stored data models. When making popup menu elements for the ProseMirror text editor in Orsn, I had to learn and make sense of the <em>PM</em> way of doing things, and find a way to reconcile that with the <em>Vue</em> way of doing things — hopefully in a way which results in the best of both worlds.</p>
<p>As usual, getting into the details of using these menu features raised questions about usability and best user experience. Much of the time I devoted to this phase of development was spent on implementing the triggering and manipulation of menus using keyboard shortcuts, as I try to support a keyboard-centric workflow for speed and convenience.</p>
<p>A significant question for a web app is whether to offer right-mouse contextual menus. This was not traditionally approved of but is becoming increasingly common in web apps (as opposed to web sites). Orsn will be usable as a desktop app as well as a web resource, which makes the question a vexed one. For now, I have avoided contextual mouse menus and gone for key-triggered contextual menus instead:</p>
<ul>
<li>@ key opens 'mentions' menu for linking to other internal resources such as cards, pages, people</li>
<li>Forward slash key opens main actions menu</li>
<li>Hash key opens actions menu with header options only</li>
<li>Selecting any text by mouse or keyboard opens a formatting toolbar</li>
</ul>
<p>Some wheels had to be reinvented with this approach. For example, if the cursor in the text editor is on the right hand of the screen, the actions menu has to display its dropdowns in a right-to-left direction rather than a left-to-right one, and the left and right arrow key actions need to be swapped, when moving between menu items:</p>
<p><img src="/images/development_diary/inline_toolbars2.gif" alt=""></p>
<br>
<br>
<br>
<br>
<p>Such details emerge just when you think you're about done. It's true that when making something, the last 20% takes 80% of the development time. More or less. In the end, the functionality is taken for granted by the user, when they have seen similar features in other apps, and they perhaps only notice it when it doesn't work, or is unintuitive. But that's OK. As a developer I still get a kick out of making these things work.</p>
<p>Now that Orsn v2 has the infrastructure in place for text editor menus, additional menu options and menu functionality can be added as required. So it's time to make progress with other features.</p>
<p>Slowly.</p>
<h3>Contact</h3>
<p>Find me on the fediverse (Mastodon) <strong>@Lemmy@post.lurk.org</strong>, or send an email to: <strong>info [at] orsn.io</strong></p>
]]></content:encoded>
      <enclosure url="https://orsn.io/images/development_diary/insert_mentions2.gif" type="image/gif"/>
    </item>
    <item>
      <title>Typescript makes you think</title>
      <link>https://orsn.io/v2/2025-04-18.html</link>
      <guid>https://orsn.io/v2/2025-04-18.html</guid>
      <source url="https://orsn.io/rss.xml">Typescript makes you think</source>
      <description>Enforcing reflexivity and consistent structure in web apps.</description>
      <pubDate>Fri, 18 Apr 2025 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>18th April 2025</h1>
<h3>Typescript makes you think</h3>
<p>Typescript is <a href="https://www.typescriptlang.org/" target="_blank" rel="noopener noreferrer">'JavaScript with syntax for types.
TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.'</a></p>
<p>I definitely have an ambivalent relationship with Typescript, but I am quite clear on the benefits it brings to my development process.</p>
<p>The ambivalence comes with the desire to be, sometimes, spontaneous, creative in the moment, to extemporise and to follow inspiration wherever it might lead. Or just to be lazy. Typescript to some extent limits those tendencies, in that everything acquires an additional step, either because of the need to define types, or more often, to work around type definitions which have previously been created. <em>It forces the programmer to confront structural questions</em>.<br>
Also, when using Typescript, code loses its clean lines. It becomes more verbose. Keyboard characters jostle for meaning, depending on where they are applied. Abstractions are rife. At times, the whole thing becomes arcane, obscuring the logic of the code, which might previously have been discernable in the code <em>structure</em>, in its sentences, phrases and syllogisms.</p>
<p>However, it is inevitable in a complex app that even after any improvisory moment, a process of careful structuring and organising will be required.
The virtue of Typescript is that it forces you to develop a more formal structure and stick to it. It forces you to do 'slow thinking'. Sometimes that feels onerous. But that careful building of structure is, like it or not, what programming really <em>is</em>.</p>
<h3>What is normal?</h3>
<p>Web applications are often complicated because they have multiple possible points of interaction. A value can be updated in a sidebar, a content panel or a pop-up box. There are numerous points of entry, unlike a game which runs a single process at 30 frames per second in a loop. So it is vital to have a single source of truth and to apply updates consistently, so that the most recent change is universally applied. That means (for me at least) having a centralised 'store' of data values in the application.</p>
<p>I was finding, in spite of adopting this architecture, that in Orsn, my handling of data was leading to inconsistencies and some errors. It turned out that this was because my data store was not really acting as a single 'source of truth'. Why not?</p>
<p><a href="https://www.wikiwand.com/en/articles/Database_normalization" target="_blank" rel="noopener noreferrer">Data normalisation</a> should be a familiar set of principles, even by intuition, to anyone who has worked with relational databases. They are principles which are designed to reduce redundancy and ensure data integrity. They prevent the same data from being saved in more than one place, which can lead to complexity, inconsistencies and errors. While observing such principles carefully in my database (on the server), I was not applying them consistently in my data store (on the user computer–usually called the 'client' but who's to say what this relationship is?).</p>
<p>To take a simple example:</p>
<p>In the database we have a table to store <strong>Cards</strong>, and a table to store <strong>Tags</strong>. Card have Tags. Multiple Tags in some cases. Tags belong to Cards. Multiple Cards in some cases. So it's a 'many to many' relationship. In such a scenario we need a third database table to store the relationship between Cards and Tags. But we don't save the whole Tag or Card (name, author, timestamp, etc.) to the third table: instead we store references to entries in the other tables. 'Tag number 1 is related to Card number 3.' etc.</p>
<p>Meanwhile, back at the app, we want to load up some Cards and their Tags. So we download the cards and tags from the database and put them in our data store. Thing is, it's quite easy to download 'whole' cards and their 'whole' tags as a single structured object from the database, and this is a convenient data model to use in the store. This way, every time I fetch a card from the store, I also have access to its tags, with all the tags' properties. That's fine... until I need to have a page in my app for managing all tags. In that case it makes sense to have a dedicated place in the store just for tags, which again I download from the database. Now we are in a bad position because 'complete' tags are stored in two places in my store, and if I update them in one place, I need to remember to update them in the other place too.</p>
<p>This unnormalised store structure is to some extent encouraged by the affordances of some code libraries for querying databases (I use <a href="https://vincit.github.io/objection.js/" target="_blank" rel="noopener noreferrer">objection.js</a> for Orsn), as they allow for the easy downloading, in a single operation, of data objects and all their related objects as a single entity, even though they may be stored in different database tables. In some contexts, a store structure like this, with duplicate entries, might be manageable, but as complexity increases, so does the potential for errors.</p>
<h3>Typescript to the rescue</h3>
<p>Typescript is not really the saviour here, but when I adopted a more stringently normalised model for my data store, I was able to use Typescript to clarify the nature of that model and enforce its use throughout the development process.</p>
<p>The fact that Typescript is a superset of javascript, and a <a href="https://www.wikiwand.com/en/articles/Structural_type_system" target="_blank" rel="noopener noreferrer">structural typing system</a> as opposed to a nominal one, gives it flexibility suited for this use case. Instead of creating a completely new set of normalised data models to use in my store, I was able to selectively adapt the shape of the existing 'full' models, to be normalised ones:</p>
<div class="language-typescript line-numbers-mode" data-highlighter="prismjs" data-ext="ts" data-title="ts"><pre><code><span class="line"></span>
<span class="line"><span class="token keyword">export</span> <span class="token keyword">class</span> <span class="token class-name">Card</span> <span class="token keyword">implements</span> <span class="token class-name">SearchableModel</span> <span class="token punctuation">{</span></span>
<span class="line"></span>
<span class="line">  <span class="token keyword">static</span> <span class="token keyword">readonly</span> fieldsToSearch <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'title'</span><span class="token punctuation">,</span> <span class="token string">'blocks.body'</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">  id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span></span>
<span class="line">  title<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span></span>
<span class="line">  blocks<span class="token operator">:</span> Pick<span class="token operator">&lt;</span>Block<span class="token punctuation">,</span> <span class="token string">'id'</span><span class="token operator">&gt;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">  tags<span class="token operator">:</span> Pick<span class="token operator">&lt;</span>Tag<span class="token punctuation">,</span> <span class="token string">'id'</span><span class="token operator">&gt;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">  projects<span class="token operator">:</span> Pick<span class="token operator">&lt;</span>Project<span class="token punctuation">,</span> <span class="token string">'id'</span><span class="token operator">&gt;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">  stacks<span class="token operator">:</span> Pick<span class="token operator">&lt;</span>Stack<span class="token punctuation">,</span> <span class="token string">'id'</span><span class="token operator">&gt;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">  cardsStacks<span class="token operator">?</span><span class="token operator">:</span> CardStacksProperty<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">  isHighlighted<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span></span>
<span class="line">  isNew<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span></span>
<span class="line">  extensionInstances<span class="token operator">?</span><span class="token operator">:</span> Pick<span class="token operator">&lt;</span>ExtensionInstance<span class="token punctuation">,</span> <span class="token string">'id'</span><span class="token operator">&gt;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">  createdById<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span></span>
<span class="line">  createdTime<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span></span>
<span class="line">  formattedCreatedTime<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span></span>
<span class="line">  modifiedTime<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span></span>
<span class="line">  modifiedById<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span></span>
<span class="line">  accessedTime<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span></span>
<span class="line">  fieldsToSearch<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">  <span class="token function">constructor</span><span class="token punctuation">(</span></span>
<span class="line">    title <span class="token operator">=</span> date<span class="token punctuation">.</span><span class="token function">getNowFormattedForCardTitle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    tags<span class="token operator">:</span> Tag<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    projects<span class="token operator">:</span> Project<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    stacks<span class="token operator">:</span> Stack<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    blocks<span class="token operator">:</span> Block<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    cardsStacks<span class="token operator">:</span> CardStacksProperty<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    createdById <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">,</span></span>
<span class="line">    createdTime <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">,</span></span>
<span class="line">    modifiedTime <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">,</span></span>
<span class="line">    modifiedById <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">,</span></span>
<span class="line">    accessedTime <span class="token operator">=</span> <span class="token string">''</span></span>
<span class="line">  <span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>title <span class="token operator">=</span> title<span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>tags <span class="token operator">=</span> tags<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>tag<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> id<span class="token operator">:</span> tag<span class="token punctuation">.</span>id <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>projects <span class="token operator">=</span> projects<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>project<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> id<span class="token operator">:</span> project<span class="token punctuation">.</span>id <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>stacks <span class="token operator">=</span> stacks<span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>cardsStacks <span class="token operator">=</span> cardsStacks<span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>blocks <span class="token operator">=</span> blocks<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>block<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> id<span class="token operator">:</span> block<span class="token punctuation">.</span>id <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>createdById <span class="token operator">=</span> createdById<span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>createdTime <span class="token operator">=</span> createdTime<span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>modifiedTime <span class="token operator">=</span> modifiedTime<span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>modifiedById <span class="token operator">=</span> modifiedById<span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>accessedTime <span class="token operator">=</span> accessedTime<span class="token punctuation">;</span></span>
<span class="line">    <span class="token keyword">this</span><span class="token punctuation">.</span>fieldsToSearch <span class="token operator">=</span> Card<span class="token punctuation">.</span>fieldsToSearch<span class="token punctuation">;</span></span>
<span class="line">  <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Instead of having an array of full Tag objects in its <code>tags</code> property, each Card now only stores the <code>id</code> value of its Tags, in a direct reflection of the normalised server database structure. This is achieved using the Typescript <code>Pick</code> feature, which allows for declaration of a partial type based on one previously declared. A nominal type system might have required the declaration of entirely new classes.<br>
This means that when the app retrieves Cards from the cards store, it now has to get the related Tags from the tags store too. But this additional step can be incorporated into the Cards getter method in the cards store, so it doesn't lead to additional complexity in everyday use. With this approach data integrity in the store is much improved, and in this example, in spite of my previous complaints about its readability, the use of Typescript in the class definition is helpfully explanatory of how the data is structured.</p>
<h3>Contact</h3>
<p>Find me on the fediverse (Mastodon) <strong>@Lemmy@post.lurk.org</strong>, or send an email to: <strong>info [at] orsn.io</strong></p>
]]></content:encoded>
    </item>
    <item>
      <title>Truncating a tab</title>
      <link>https://orsn.io/v2/2025-03-20.html</link>
      <guid>https://orsn.io/v2/2025-03-20.html</guid>
      <source url="https://orsn.io/rss.xml">Truncating a tab</source>
      <description>Usability in new software features, tabbed interfaces.</description>
      <pubDate>Thu, 20 Mar 2025 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>20th March 2025</h1>
<h3>Truncating a Tab, and other short stories</h3>
<p>So you decide how your interface is going to look, and you have a good idea about how to implement it. Then you get into the detail...</p>
<p>It's when you start <em>using</em> a feature yourself that you realise that the detail of the implementation is vital to usability, and to a good working relationship with the software.</p>
<h3>A Tabbed Interface</h3>
<p>In a main view in my new design, I have a tabbed interface for managing content (see main pane of image below). That's pretty straightforward to implement.</p>
<p><img src="/images/development_diary/tabbed_interface.png" alt=""></p>
<p><em>Image: Screenshot of Orsn 2 software prototype</em></p>
<p>With <strong>tabs</strong>, a tab can be as wide as the text it contains. In that case you will end up with some very wide tabs and you will be doing a lot of horizontal scrolling to be able to browse through content. So if the overall width of the tabs is wider than the browser window, it makes sense to truncate the text in the tabs, so that you can fit more into the view.</p>
<p>This is where it gets a bit tricky.</p>
<p>My Orsn tabs are not a fixed width, like those in Chrome – they are only as wide as the text in them. And do you know what, I like it like that, so I'm not going to change them to be fixed width. That means that some are narrow, some are wide, and it's not ideal to truncate every tab by the same amount. <strong>You only need to truncate the long ones</strong> when that is necessary: and when doing that, you have to take into account the extra width afforded you by <strong>narrow</strong> tabs. Otherwise, you truncate too much and your tabs don't fill all the available width of the browser, which adversely affects legibility of tab titles.</p>
<p>To cut a long story short, here is the logic I (eventually) arrived at for a satisfactory tab truncation process:</p>
]]></content:encoded>
      <enclosure url="https://orsn.io/images/development_diary/tabbed_interface.png" type="image/png"/>
    </item>
    <item>
      <title>An Idea in Motion</title>
      <link>https://orsn.io/v2/2025-03-04.html</link>
      <guid>https://orsn.io/v2/2025-03-04.html</guid>
      <source url="https://orsn.io/rss.xml">An Idea in Motion</source>
      <description>Progress update on Orsn v2 development, including interface redesign and technical improvements.</description>
      <pubDate>Tue, 04 Mar 2025 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://orsn.io/rss.xml" target="_blank" rel="noopener noreferrer">Subscribe to updates</a></p>
<h1>4th March 2025</h1>
<h3>An Idea in Motion</h3>
<p>I am making steady progress with Orsn v2.</p>
<h3>Non-Technical</h3>
<p>With v2 I have redesigned, to varying degrees, the paradigm, the interface and the database structure.</p>
<p>Now we have a simplified paradigm of Cards and Pages. Pages take over from Contexts in v1. They're extensions (plugins) and can provide custom visualisations and interactions. As part of the v2 rewrite, there will be fewer of these at first, with more attention paid to proper execution – v1 was more of a proof of concept. I will also provide templates for those who want to create their own.</p>
<p>A Project has three modes: Edit, Design and Publish. Edit is for creating content. Design is for arranging Pages, and Publish is for the presentation of the selected Pages. For the moment I am focusing solely on Edit mode.</p>
<p><img src="/images/development_diary/orsnv2_1.png" alt=""></p>
<p><em>Edit mode: a simple prototype page, with temporary content and design, showing sidebar and tabbed contents</em></p>
<p>The interface is already cleaner. In edit mode there is now only one main sidebar, instead of two. It has tabs at the top and accordion-type sections at the bottom. (Cards will have their own foldable annotation and revisions sidebars, on the opposite side of the interface, as will Pages...) Not unlike what you would see in VS Code or a similar IDE app. As before, the sidebar position is switchable in settings. This time, though, I have added some basic functionality which was missing in v1, e.g. dragging of sidebars and accordion sections to resize them.</p>
<p>Cards now have Blocks, that is separate sections for different types of Markdown content. This is still in development, but it will bring Orsn up to speed with what other Markdown editors offer. The types of Block supported will be text blocks, code blocks with highlighting, tables with some useful editing options, and LaTeX. (There are some interesting graphing options in Markdown these days but that is not a priority for now. That kind of thing can perhaps be better done in a Page extension.) I think this kind of Block concept should be familiar to anyone who has used Jupyter Notebooks or similar tools.</p>
<p>There is the option to have multiple Stacks now, in a tabbed interface. Before, there was just one Stack. A Stack is a collection of Cards. A bit like a folder, functionally, but it avoids the use of a hierarchical structure in the Cards themselves. Once you have added Cards to a Stack, you can collectively add them to a Page, if you want. You can create 'Live Stacks', e.g. a Stack based on a tag, which shows every Card with that tag. Or a Stack based on a search term. Etc. (Like 'smart folders' in some OSs.) At least you will be able to. For the moment, I am pouring the foundations, not laying the bricks.</p>
<p>A priority on the roadmap is to make it possible to assign properties to Cards. In this way, a Card in a Project will be able to have certain custom fields. As an example, you might have a Project for storing book references, in which each book's Card has ISBN and author properties. Those properties will then be accessible for visualisations or interactions in Pages, if the Card is added to a Page.</p>
<p>I won't say too much more about the database design, as it is ambitious in the features it might support in the future, but my priorities for now are more modest.</p>
<h3>Technical</h3>
<p>My starting point for updating the software was to migrate everything to Vue3 and rewrite the codebase to use Typescript. That phase is complete apart from a very few utility files which are still in javascript for the moment.<br>
I resisted Typescript to a degree in the past, in part because I like code to be readable and self-explanatory wherever possible. I also want it to look nice! Perhaps not surprising for someone who spends a lot of time building interfaces? Typescript decorates javascript to such a great extent that if you are at all unfamiliar with it, code clarity is much reduced. Also, there are certain procedural aspects about it which I found confusing. Where to put the type declarations? What's the difference between <code>.ts</code> and <code>.d.ts</code> files?</p>
<p>On the other hand... for an application of any complexity, type safety is such a boon. It forces you to think clearly and helps enforce consistency. It makes structural decisions in the code explicit. That is all-important. I don't want to say how often I have found inconsistencies in v1 of Orsn, inconsistencies which Typescript has forced me to confront and fix. Also, once you have a certain level of familiarity with Typescript, the code is still very readable. And for other confusions, such as where to declare types, there is always the option of reading the documentation or looking at other people's code.</p>
<p>So overall I am delighted with Typescript, and I can't see myself going back. It has definitely helped make clearer what is happening under the hood in all the different parts of the new Orsn.</p>
<p>The move to Vue3 is what made it possible to use more Typescript than in v1. I have seen that other javascript frameworks are trending (Svelte?) but I haven't looked into them. Vue seems to be going strong and I really enjoy its usability and the sensible structural guidelines it sets out. I used React in a former job and its language was stated very much in terms of the requirements of the framework and its logic. Vue's language is stated more in terms of the requirements of the app designer. That may make it slightly more high level in some respects, but not significantly. You still have to understand lifecycle events, data binding, all the core stuff that makes it useful.</p>
<p>As part of the move to Vue3 I also upgraded the application's store system from Vuex to Pinia. They are similar to use in a lot of ways, but the move to Pinia has allowed me to remove a lot of code, as data updates are now executed straight away in 'actions' instead of in separate 'mutations'. That is easier to read and make sense of, and more economical to write. Pinia also supports Typescript directly.</p>
<h3>The Road Ahead</h3>
<p>The path onwards is pretty clear, and I am confident about the technical side of achieving the goals. The big problem is having the time to get there. That's the battle, and of course that is the difference between an imagined app and a 'real' one. It's not properly real until you make it.</p>
<p>It's interesting trying to balance the small details against the bigger picture. You can spend your morning making a sidebar resizable, but then you have to switch perspectives and consider the overall design and purpose.</p>
<p>It would definitely be useful to hear from others with different perspectives. I don't want to spend a long time going down the wrong paths. Find me on the fediverse <strong>@Lemmy@post.lurk.org</strong>, or send an email to: <strong>info [at] orsn.io</strong></p>
]]></content:encoded>
      <enclosure url="https://orsn.io/images/development_diary/orsnv2_1.png" type="image/png"/>
    </item>
    <item>
      <title>Version 2?</title>
      <link>https://orsn.io/v2/2025-02-10.html</link>
      <guid>https://orsn.io/v2/2025-02-10.html</guid>
      <source url="https://orsn.io/rss.xml">Version 2?</source>
      <description>Plans for Orsn v2, including proposed features and design decisions.</description>
      <pubDate>Mon, 10 Feb 2025 00:00:00 GMT</pubDate>
      <content:encoded><![CDATA[
<h3>Version 2?</h3>
<p>The first version of Orsn was to an extent a proof of concept and was not widely released. Now I want to get it to a more 'finished' state, one where I will feel happier about properly sharing the software. Some changes are required to make the software more robust, and I have ideas of how to make it more useful and usable, too. These are sufficiently different from what is there now to warrant a new version number and prompt the sense of a fresh beginning.</p>
<h3>He's a man, with a plan...</h3>
<p>I have mostly completed making updates to Orsn to use Vue 3, Typescript and a more modern text editor library, <a href="https://codemirror.net/" target="_blank" rel="noopener noreferrer">Codemirror</a>. However, rather than simply making a reproduction of the existing version, I'm now pausing to redesign the software.</p>
<p><strong>Before I list the proposed updates I want to summarise the overall goals for the software:</strong></p>
<ol>
<li>Document and share research</li>
<li>A creative interface for developing, organising and inspiring ideas, and optionally to 'show workings'</li>
<li>Easy to use software, ideal for individuals and small teams as well as institutions</li>
<li>Geared primarily towards humanities research and writing, but with support for data-based research/digital humanities</li>
<li>Encourage open scholarship practices</li>
<li>For knowledge in-the-making: allow for rewriting, annotation, multiple perspectives, iterative versioning</li>
</ol>
<p>Orsn is primarily (though not only, as we will see) a text-wrangling software which uses Markdown for text formatting. Markdown is a plain text format which makes content easily storable, reproducable, editable and versionable, for example in a Git repository. It also supports the attractive and readable formatting of text for human consumption.</p>
<p>Using Markdown is an important part of working towards the goals listed above, in particular, 5) and 6).</p>
<p><strong>Users should be able to publish an Orsn research notebook to a Git repository</strong>, where it can be accessed, annotated and further developed by others – or at least it should be downloadable for others to explore it in detail in their own Orsn application. This shouldn't be something which is technically difficult for users to do. Orsn should offer simple controls for publishing research notebooks to Github or equivalent public repositories, and for cloning projects from repos to their desktops.</p>
<p>Operating at a small scale like this is vital to my aspiration for Orsn to support open scholarship and inclusive research. Orsn should be an alternative to research platforms which require an institutional team to maintain, and research projects which require large funding investments and therefore do not have the option of failing. Research should be capable of being a low-stakes activity which allows for experimentation, playfulness, and learning from mistakes. And it should potentially be open to many participants, not just those sanctioned by academic institutions.</p>
<p>Orsn is built using web technologies, so Orsn projects can be published as websites. However, Orsn can also be used as a cross-platform desktop app, in offline mode. This maximises its potential for inclusive use. One of the goals of the software is to provide a digital-first format for research outputs, one which properly exploits the potentials of digital media and networks, and avoids the syndrome of presenting research via 'website with downloadable PDFs'. Having a web-based format of exchange for Orsn projects allows users to exchange projects for offline desktop exploration, while retaining the benefits provided by digital interactions.</p>
<h3>Proposed features in v2:</h3>
<p><strong>Simpler structure</strong></p>
<ul>
<li>
<p>Instead of <em>Cards, Contexts and Pages</em>, Orsn v2 has <strong>Cards</strong> and <strong>Pages</strong>.</p>
</li>
<li>
<p>Cards are like index cards in a filing system, with text and images. Cards now have rearrangeable blocks for specialised content, such as formatted computer code, LaTeX, or tables – anything that can be rendered as Markdown.</p>
</li>
<li>
<p>Cards can be arranged on multiple 'stacks' or 'shelfs', presented as tabs</p>
</li>
<li>
<p>Pages are for aggregating cards, and for long-form text (and images). But they can also be rendered by extensions (plugins) for different kinds of visualisations, as Contexts were in orsn v1: Map page, Timeline page, Graph page, etc.</p>
</li>
<li>
<p>Each Project has a contents page for organising and presenting Pages.</p>
</li>
<li>
<p>All types of content have an optional annotation column.</p>
</li>
</ul>
<p><strong>Extensions ecosystem</strong><br>
Page extensions will be <code>npm</code> packages, hosted on a public repository. There will be a template for creating your own plugins in javascript or typescript. Authors will be encouraged to share their extensions with the community.</p>
<p><strong>Card properties</strong><br>
All cards already have basic properties, such as <code>title</code>, <code>body</code>, <code>author</code>, date of creation. In v2, Cards can be assigned additional project-wide properties, e.g. latitude and longitude, height, weight, start-date, end-date, geoJSON, etc.
Such properties can then be made use of in Page views which depict those Cards and their properties, for example as graphs, maps or interactive visualisations.
One use case would be that Card properties are drawn from an imported standardised vocabulary.</p>
<p><strong>Versioning</strong><br>
A more robust version of the current revisions system for cards, with an improved visual interface. <em>To be decided</em> whether to extend versioning support to Card Properties.</p>
<p><strong>Semantic support</strong><br>
Orsn does not aim to be a fully-fledged platform for semantic structuring of data, as this approach is not a good fit with its overall philosophy. However, there is potential to use semantics to create relationships between entities, using established ontologies if desired. This is facilitated by the introduction of Card Properties. These relationships can then be represented using custom Page extensions. (Semantic relationships would be stored in a relational database format, to maintain the emphasis on ease of access to Orsn, with minimal setup or technical skill requirements.)</p>
<p><strong>Publishing support</strong><br>
An option to publish project as a set of Markdown files, and export these to an online Git repository. Also, the option to load in a project from an online Git repository.<br>
<strong>Note.</strong> Cards can be fully represented as Markdown text and are therefore easily subject to versioning. Pages may be a mixture of Markdown text blocks and other visual elements, e.g. a Leaflet map. In a Git repository, such content would need to be represented as a JSON config file, specifying the extensions to load into Orsn, and their version numbers, in order to reproduce the content described. (Just as a <code>package.json</code> file does in a node project.) The installation of the necessary extensions could be automated as part of the project import process in Orsn. <em>To be decided</em>: how Card Properties should be handled in this scenario. Properties data could potentially be exported in JSON or yaml format, which could be used for repository storage, but then imported into the Orsn database for more user-friendly use via Page extensions.</p>
<p><strong>Easier Markdown experience</strong><br>
New WYSIWYG editor for markdown text, for those unfamiliar or uncomfortable with editing Markdown directly, as well as 'source view' markdown editing and split-screen with preview.</p>
<h3>Decisions and Priorities</h3>
<p>What I need most to make v2 is time, which is a costly commodity, unfortunately. If you think a go-fund-me type project to develop the software over a fixed time-span is a feasible idea, let me know.</p>
<p>My philosophical approach to Orsn and open scholarship prompts me to propose versioning and annotation, as well as easy online publishing and sharing, as important features. However, features like versioning add programming complexity – which is fine, but detracts somewhat from the aesthetic pleasure of a simple codebase, and its accessibility. However, I have concluded that the best way to engage other developers in this project is by allowing them to create custom extensions, so this may not be so significant...</p>
<p>Should versioning of text blocks be integrated into the proposed 'export to Git' feature, so that each recorded text update is written as a commit in the exported repository? Should non-textual data (Card Properties) be versioned?</p>
<p>Are other features, such as semantics, or something else I've failed to mention, more important?</p>
<p>I am strongly conscious of the potential gap between the ideals of this project and the practicalities of how people might actually use it. Do they really want to have versioning for data, for example? Do researchers really want to 'show their workings', and is it better to just focus on allowing them to share their final draft effectively?</p>
<p>I also want to support the user who uses Orsn for purely personal documentation of ideas and research, and for creating documents. That is how I have been using Orsn myself for many years now.</p>
<p>In short I need advice on priorities! If you have thoughts, find me on the fediverse @Lemmy@post.lurk.org, or send an email to: info [at] orsn.io</p>
]]></content:encoded>
    </item>
  </channel>
</rss>