Section Editor - Prototype

This is an effort to create a section editor in Tiddlywiki

Definition: A section is part of tiddler started with a heading eg (! H1, !! H2, ...)

A section editor work on a elementary tiddler like below

!  Level one
This is a sample text

!! Level two
This is another part and it may have //italic//, ''bold'', etc...

!! Level two two
Other wikitext format are allowed

What does Section Editor do?

  • adds a button to each heading
    • the button has two states edit/done
  • on edit, a local editor will be opened and user can ONLY see that section and edit it
  • when finish, clicking on done button will update the tiddler with changes

Please give your inputs

Special tanks to: @Mark_S, @twMat, @TW_Tones, @saqimtiaz, @EricShulman, @sull-vitsy, @Charlie_Veniot

This the first beta release as plugin:

This is a beta version and will be modified without notice! Use only for test purpose!

Code and demo

To give a try:

  1. download the plugin from Section Editor — create, edit, fold, manage sections
  2. drag and drop into https://tiddlywiki.com/prerelease
  3. create a new tiddler with an empty field: se-type
  4. add some contents with few headings (work for h1, h2)
  5. save, hover your mouse and see the section edit button
  6. click to edit, if you like save the changes or cancel changes
1 Like

First prototype

  • This is a prototype, this is a preliminary draft, at this stage, the code works on an external tiddler!
  • Only functionality is tested, the UI (presentation) will be tweaked later (stay tunned)

Part of code

  1. split a source tiddler text into parts by headings
  2. display parts
    2.1 use a toggle button to show/edit parts
    2.2 on edit, copy part into a temp tiddler
    2.2 after edit (done) search-replace the old text with new one
    2.3 update the source tiddler

helper macros

\define stateTid() $(stid)$/state/$(cnt)$$(cnt1)$
\define editTid()  $(stid)$/content/$(cnt)$$(cnt1)$
\define source() Test

toggle button

\define toggle-button(stateTiddler, onlabel:"On", offlabel:"off")
<$reveal type="nomatch" state=<<__stateTiddler__>> text="edit">
<$button set=<<__stateTiddler__>>  setTo="edit" actions=<<onactions>> >{{$:/core/images/edit-button}}</$button>
</$reveal>
<$reveal type="match" state=<<__stateTiddler__>>  text="edit">
<$button set=<<__stateTiddler__>>  setTo="show" actions=<<offactions>>>{{$:/core/images/done-button}}</$button>
</$reveal>
\end

actions on toggle

\define onactions()
<$action-setfield $tiddler=<<editTid>> $field=text $value=<<currentTiddler>> />
\end
\define offactions()
<$vars for=<<currentTiddler>> with={{{[<editTid>get[text]]}}}>
<$action-setfield $tiddler=<<source>> $field=text $value={{{[<source>get[text]search-replace<for>,<with>]}}} />
</$vars>
search-replace

\end

inline editor (edit/view)

\define feditor()
<$macrocall $name=toggle-button stateTiddler=<<stateTid>> onlabel="edit" offlabel="show"/>


<$reveal state=<<stateTid>> type="nomatch" text="edit">
<$transclude field=title mode="block"/>
</$reveal>
<$reveal state=<<stateTid>> type="match"   text="edit">
<$edit-text tiddler=<<editTid>> field="text" tag=textarea class="w-100"/>
</$reveal>

\end

Splitter

<$vars pattern="\n\!"
  src={{{[<source>get[text]]}}}  stid=<<currentTiddler>>>
<$list filter="[<src>splitregexp<pattern>!is[blank]first[]]" counter=cnt1>
<<feditor>>
<$list filter="[<src>splitregexp<pattern>!is[blank]butfirst[]addprefix[!]]" counter=cnt>
<<feditor>>
</$list>
</$list>
</$vars>

Test

To give a try (only work in TW 5.2.0+)

NOTE: I will correct names, ids, … later for better readability

@boris - would you mind to convert this post to a wiki, allow other contributors can directly edit!

This looks like a very complicated version of my subsume plugin. Subsumes are basically section headers, where the section is transcluded below the header. And the subsume-edit macro gives you the edit button to the right of the section header.

I have been thinking about re-doing the Subsume plugin to incorporate a toggle button, so that you could work in subsume-edit, with the edit button at the side of the section header, then click a button to change all the subsume macros to view mode, so the edit button would be hidden.

@DaveGifford
Hi David,

NO, it is not! I can say it is not even similar to subsume!

It is a section editor! This concept comes from dokuwiki and wikimedia!

It will work later using a simple field value or tag!

Including other tiddlers in a tiddler with an edit/link/button is a common knowledge in Tiddlywiki and you can find it in many user wikis out there!

TW-Scripts has bunch of folding editors, inline editors and tools to include other tiddlers in a master tiddler! BUT none of them can do section editing!

So this is not re-doing subsume! I think you post your opinion before you test the code I shared!

2 Likes

Nice job @Mohammad! I agree that for some of us (like me), the distinction between a single-tiddler storage mechanism vs. a multi-tiddler storage mechanism is a key decision point. Similar philosophy to why I made my “Sticky Todo” thing the way I did (similar pattern, some regex + search-replace). There are some benefits in terms of performance, searchability of topics etc. that are worth it to sometimes use a single-tiddler approach like this. I’ll bookmark this one for later to remember the pattern you used.

Looking forward to seeing it at a later, more polished state - but looks good so far!

1 Like

Thank you @stobot. Your Sticky Todo is actually a great addition! It shows how one can work on the same tiddler and do actions in place! So, I absolutely acknowledge your contribution!

In Commander, we have a search and replace (we is not royal we, here we = BTC, Mark_S, TiddlyTweeter and kookma) . It called SNR and has been published separately! It is very powerful, allows you to search and replace anywhere you think even in title!

1 Like

My apologies, Mohammad, I did not write to offend you or belittle this accomplishment. I was just pointing out the similarities for the end user.

In reading Stobot’s comment and your response, I now understand that this involves sections within the tiddler itself rather than grabbing from other tiddlers. That is a big step forward. Kudos to you, and I look forward to seeing how this develops.

1 Like

Hi David,
You are highly welcome and no need for apology! I have always acknowledged your contributions, ideas and tools! and we (I and other users) benefit from them! Thank you!

I think you should use custom elements

<mo-section>
stuff
</mo-section>

I appreciate you want to use Hn tags (and they’re ready to go in the toolbar) but setting aside your very own elements seems better somehow (gives you a bit more control over their meaning, too).

I’m sure you could add them to the toolbar if you wanted to.

Other than that, great piece of work @Mohammad !

@Mohammad good work so far and an important objective. I would still recommend looking into existing solutions for code tricks if you find any barriers.

I support @CodaCoder suggestion of custom tags but simultaneously support your desire to base it on headings because they do represent the HTML “semantic” section.

  • If I may suggest that you try and keep the actual “wiki-markup and or html tags” sections - a configurable element. I can’t voice all the reasons easily but I think this will help in the long run.

Personally I am keen to make a generic solution for extracting multiple and nested content between markup or html tags, which would resemble a core mechanism of the solution you are building. I will see if I can do it in coming days. We can see if it can inform your project.

I understand your in prototype mode but can I suggest one nice approach is rather than place buttons along side content actually display the content from inside a button, then clicking the content triggers edit on the content section. The button widget permits tag=div and with class="tc-btn-invisible" can look like the original wikitext. I think once you move beyond prototype it may be sufficient just to have a tooltip appear to indicate an editable section. Yes once editing have a tick button.

Another suggestion is since clicking to edit a section is a trigger it is important to allow other actions to be triggered. In particular for this solution you could store the section content elsewhere for restore, history and backup.

Good work, I will continue to monitor this work.

Actually there is an HTML section Tag

Good idea.

1 Like

This looks exciting! Have you seen jd’s paragraphs macro? The ui is similar. The state tiddlers containing the section being edited gets deleted upon save.

I tried adding headings while editing a section. It works as expected, that when you save the section, it creates new sections under it. I’ll play around with it more later. Thanks!

1 Like

Paragraph works on other tiddlers! It is kind of inline editor. There are similar tools out there (see TW-Scripts)! the big difference here, you work on the same tiddler.

@TW_Tones - thank you for comments and ideas!

Using html tags like <section>....</section> has been already introduced!
Please see the find-macro from kookma and summary from Tobias Beer!

Example:

<<show-macro "$:/core/macros/toc">>
  • see how find macro split the $:/core/macros/toc into individual sections delimited by \define, \end. It has been used as a tool to explore complex codes created from several macros!

So, using delimiters like start/stop has been already developed!

The core of current solution is to work on pure wiki text without introducing extra tags, … It works on a semantic section. It is an article/essay/homework/… contains natural sections separated by headings!

I think the streams from @saqimtiaz can do this job in the best way! maybe a subplugin can be developed! Streams has beautiful semantic UI, supports shortcut keys, double clicks for edit and many more… I think stream also faster than wikitext script here!

I prefer wikitext headings over <section></section> tags too. It would be more practical for non-coder users, especially those with no html knowledge. Exclamation marks are easier to type too.

The only problem I encountered with your prototype is that when the text starts with 2 linebreaks, it gets treated as a new section and an edit button appears. I think this has something to do with the regexp or the splitting? It’s an unconventional situation though, no one would actually do this, unless by accident.

Text:



! Heading 1
text

Output:

image

This becomes a problem when you erase the contents of the preface section. Erasing the contents of a section leaves two linebreaks behind in the source tiddler. So when you erase the preface section, the two linebreaks are counted as a section.

Maybe there could be an section deleting mechanism in the future?

I, personally, would not need an add section feature. I enjoy the current way of making new sections, which is to add heading markup and some text at the end or at the top. This behavior is a good feature for me.

Thank you @sull-vitsy! I can confirm the bug!
For adding new section, I like your idea, so we keep it as is for simplicity!

@sull-vitsy - this is a simpler solution address the bug (an extra empty line)

\define stateTid() $(stid)$/state/$(cnt)$ 
\define editTid()  $(stid)$/content/$(cnt)$
\define source() Test


\define onactions()
<$action-setfield $tiddler=<<editTid>> $field=text $value=<<currentTiddler>> />
\end
\define offactions()
<$vars for=<<currentTiddler>> with={{{[<editTid>get[text]]}}}>
<$action-setfield $tiddler=<<source>> $field=text $value={{{[<source>get[text]search-replace<for>,<with>]}}} />
</$vars>
search-replace

\end

\define toggle-button()
<$reveal type="nomatch" state=<<stateTid>> text="edit">
<$button set=<<stateTid>>  setTo="edit" actions=<<onactions>> class="float-right">{{$:/core/images/edit-button}}</$button>
</$reveal>
<$reveal type="match" state=<<stateTid>>  text="edit">
<$button set=<<stateTid>>  setTo="show" actions=<<offactions>> class="float-right">{{$:/core/images/done-button}}</$button>
</$reveal>
\end


\define feditor()
<<toggle-button>>
<$reveal state=<<stateTid>> type="nomatch" text="edit">
<$transclude field=title mode="block"/>
</$reveal>
<$reveal state=<<stateTid>> type="match"   text="edit">
<$edit-text tiddler=<<editTid>> field="text" tag=textarea class="w-100"/>
</$reveal>

\end

<style>
.w-100{width:100%}
.float-right{float:right; color:red}
</style>

--- Start

<$vars pattern="\n\!" nonWhitespace="[^\s]"
  src={{{[<source>get[text]]}}}  stid=<<currentTiddler>>>
<$list filter="[<src>splitregexp<pattern>!is[blank]first[]] :filter[get[title]regexp<nonWhitespace>] 
               [<src>splitregexp<pattern>!is[blank]butfirst[]addprefix[!]]" counter=cnt   >
<<feditor>>
</$list>
</$vars>

That removed the bug of picking up the first two linebreaks as a section!

But it doesn’t show a preface anymore, either. :open_mouth:

Text:

Preface of text. Test. Test. Preface text.

! Level one (!)
This is the first part

* Hirad
* Pouri
* Jeremy

!! Level two (!!)
This is the second part

!!! Level three (!!!)
Hello Mohammad. This is third part

Crude test

This some text in the last part

Output:

image

Your prototype makes me think a bit of this demo Streams — single tiddler

One could imagine a customized version of Streams that worked with headings rather than lists. What concerns me with these kinds of approaches is that it requires proper formatting in the text of the tiddler, which can’t be assured and without which the parsing/splitting fails. This may however be a lot easier with headings than with lists.

Similarly it would be completely possible to customize Streams to generate the same end viewing experience as Dave’s Subsume, but with a more fluid writing experience. It just needs for someone to get their hands dirty.

Streams is actually almost entirely wikitext. The only JavaScript sprinklings are in a custom widget for more flexible keyboard shortcuts, or for swiping.

1 Like

Thank Saq!

If it is pure wikitext, then I will give a try!