Presentation Mode

I had tried briefly Inkdrop before, but had no time to dig deep. But now I noticed that it has a possibility to create plugins by myself. The creator inside me woke up and I came with one idea that I would want to create.

Not sure if this is possible to do with plugin or is someone already doing something similar. So I thought to ask first before I spend too much time to experiment on this.

I found an interesting library, reveal.js, that could be used to create presentation with Markdown. And I like the idea of having some syntax to say if it is a normal slide or vertical slide etc. And the speaker mode is a good one (showing next slide, speaker notes, time).

Here are my findings/questions so far if I had understood the documentation of Inkdrop and reveal.js

EDIT I think I found simpler way to use the reveal.js, with the reveal-md.

  • reveal.js needs it’s web server to run locally
  • I should implement custom Markdown Renderer on Inkdrop?
  • Then export the file from Inkdrop for the reveal.js already running.

The main goal for me is to have a presentation that I can show even on offline right from the Inkdrop.

Is this possible or is it just too big cake to eat? What would be good steps to start with the idea if it is possible?

2 Likes

I decided to give it a try.
Currently I’m able to call reveal-md from my Inkdrop plugin and open the browser window with dummy-markdown file (hardcoded value for now).

Next steps that I think I should take:

  1. able to export to Markdown from Inkdrop (it has the feature, but I need the exported file immediately, its filepath)
  2. send that exported Markdown file to reveal-md

Also I need to figure out how to make the Inkdrop renderer to show the preview in the editor somehow usable. As now it can not support the needed syntax for reveal-md to work correctly.

1 Like

Hi Sami,

Great to hear that you are trying to create a plugin!
Your idea sounds great. It’s like the feature Evernote supports.
You can add a custom component to display the presentation preview using Electron’s webview and here is how to customize the app layout.
You can get the current editing note state via Redux store.

Hope that helps for your development!

1 Like

Hi Takuya,

Thanks for those links!

I tested the webview and I’m able to show the slides now somehow in the Inkdrop.

I was not able to use the MessageDialog as an example how to show it as modal / popup as I didn’t figure out how to resize it correctly. And would be better to have it as a separate window perhaps.

Now on my current quick and dirty test I just create my custom view with the window width and height. It now basically takes the whole window where Inkdrop is.

When I tried to open the “Speaker View” (pressing button S) that is the feature of reveal.js, the Inkdrop gave me the following error (attached picture).
I have added the allowpopups prop for my webview, so I think it might have been prevented from the current BrowserWindow? I don’t know the Electron so well :sweat_smile:

But little step by step :slight_smile:

1 Like

Glad to see you made a progress!

MessageDialog should be resized based on its content, so I guess you have to add a CSS to explicitly set the content size.
But as you said, you better make a separate BrowserWindow dedicated for the presentation, loading an HTML which reloads when a note got updated by watching a temporary Markdown file or something. It’s kind of tricky though.
That’s weird regarding the error, because the app basically doesn’t restrict such behavior.
But I guess it’s perhaps due to Content Security Policy in the Inkdrop’s HTML.
So, I suggest that you make a BrowserWindow so that you can have full control on it.

1 Like

Thanks :blush:

I will try to learn more about the BrowserWindow and see how it used and such.
Having fun trying to create a plugin and able to write my finding down to Inkdrop.

Today’s progress is that I am able to show the markdown from the Inkdrop editor on the opened BrowserWindow. And the speaker view works :slight_smile:

Possible next steps

  • Saving markdown as temporal file or so on the plugin’s side
    • Now as quick-and-dirty solution I save it on the server running reveal-md)
  • Some watch logic for the file to reload after save
  • Somehow to add support to Inkdrop’s preview for the reaveal.js syntax so that it is easier to do
    • No need to constantly open the separate window to see how presentation now looks
  • Cleanup the code :sweat_smile:
2 Likes

Cool! Good to know that you could successfully create a BrowserWindow.
Good luck with the remained steps :slight_smile:

Small update from the development

  • Markdown is now saved to user’s “AppData” folder, depends which OS is used.
  • Presentation is saved everytime when refreshing the presentation from plugin and BrowserWindow updates to show it
  • Code is cleaned up a little

Next steps

  • Catch se Inkdrop’s save and then call to export the presentation automatically
    • some option/setting to turn it on manually or only when “Presentation Mode” is activated
  • Better workflow, user experience -> toolbar button(?), item to plugins-menu etc.
  • Showing notification / dialog if there is error, loading or something.
  • First-time-setup / help-screen to inform user how to use, what are the requirements etc.
  • Supporting the presentation syntax in the Inkdrop’s preview
    • currently “the workaround” when doing presentation, you just don’t need the Inkdrop’s preview as you can see the presentation in another window.
  • Configurable settings for few settings of plugin
  • Emoji support
  • More cleanup and refactoring

Challenges that I had

I had problems when I tried to start the reveal-md straight from the plugin. I tried this so that it is automatic as possible for the user.

It seems that it was somehow started in “isolated mode”, so that it couldn’t correctly work when giving files to it from outside of the plugins folder. But on the other hand I understand why it might be isolated. And also it was not so reliable way to do it and might have too much issues on different OS’es.
I lost few nights with these :sweat_smile:

So I deciced that reveal-md need to be started manually by the user, but I just need to properly show instructions for the user. Therefore I’m planning to show some first-time-setup/help screen for that.


p.s I like to post these updates, so that it keeps me pushing forward even if I face some challenges during the journey :smiley:

3 Likes

I’m enjoying seeing your progress!
I guess it would be helpful for other people trying to create a plugin as well.
Keep it up!

Having some difficulty with markdownrenderer

Trying to write custom markdownrenderer plugin for the required use of dashes in reveal.js. So that I could show something nice instead of the default hr-tag that the four dashes generate. With three it seems to make the content inside of not rendered at all.

So what I thought was Inkdrop is maybe using some yaml plugin for remark (remark-frontmatter) that will break “three dash”-case. And “four dash”-case might be catched with remark-html?

As it seems that the console.log(markdownRenderer.remarkPlugins); will not print all used plugins, so that I could add my own before the problematic ones.

Maybe because of this default behaviour described above, I can not get my own plugin to work as they have tokenized the file already?

I tested to create some simple text replace plugin and it works.

Cases I currently have challenge with

Here are the dashes I’m trying to figure out and replace it:

1.) yaml options at the start of the file

---
title: Presentation title and other properties
---

2.) for horizontal slide change

---

3.) for vertical slide change

----

And example case to get better idea

If you try this, Inkdrop by default will hide the # 2 Second slide as it is between the “three dash”-case.

---
 title: Testing
---

# 1 First

Lorem ipsum
dolor sit amet

---

# 2 Second

Lorem ipsum
dolor sit amet

---

# 3 Third

Lorem ipsum
dolor sit amet

----

## 3.1 Third, first vertical

Lorem ipsum
dolor sit amet

----

## 3.2 Third, second vertical

Lorem ipsum
dolor sit amet


---

# 4 The End

Help?

Could someone guide me a little with this if possible :slight_smile:

P.S I could force reveal-md to use different separators, but it will make the start command even longer than it should be. Would like to use the “standard” use of dashes.

Hi Sami,

Yes, the app is using remark-frontmatter to parse YAML frontmatter.
Your remark plugin is added after remark-frontmatter. Then it’s freezed and processed with remark-rehype, rehype-raw, rehype-react and custom internal plugins for Inkdrop.

The “three dash”-case is a common expression of inserting <hr> (ref: CommonMark - 4.1 Horizontal rules).
I don’t know where the “four dash”-cases is processed but you can override this behavior by making a parser which runs before remark-parse's default thematic-break like so:

export default function remarkPageBreakParser() {
  const Parser = this.Parser
  const blockTokenizers = Parser && Parser.prototype.blockTokenizers
  const blockMethods = Parser && Parser.prototype.blockMethods

  if (blockTokenizers) {
    blockTokenizers.revealPageBreak = revealPageBreak
    blockMethods.splice(
      blockMethods.indexOf('thematicBreak'),
      0,
      'revealPageBreak'
    )
  }
}

const C_DASH = '-'
const C_NEWLINE = '\n'
const DASH_COUNT = 4

function revealPageBreak(eat, value, silent) {
  const character = value.charAt(0)

  if (character !== C_DASH) {
    return
  }

  const indexEOL = value.indexOf(C_NEWLINE)
  const subvalue = value.substr(0, indexEOL)

  if (subvalue.length !== DASH_COUNT) {
    return
  }

  if (silent) {
    return true
  }

  return eat(subvalue)({
    type: '????',
    value: '????'
  })
}

Hope that helps!

1 Like

Thanks a lot for that Takuya!

It works!

With the help of that I’m now able to show both the horizontal (— = three dashes == hr) and vertical (— = three dashes) slide change!
Currently with only simple text presentation, as I could not yet figure out how to use React component with the thematicBreak, if possible. But at least I can show some simple visualization to the user :slight_smile:

Just a side note

Like in the previous example I provided, hr, only works if user will add atleast 1 empty space before it.
CommonMark documentation says:

A line consisting of 0-3 spaces of indentation, followed by a sequence of three or more matching - , _ , or *

If user will not give the space before three dash in Inkdrop, the content inside is hidden in preview. But when I figured that the space is needed for it to work correctly, I got it working.

Example with those three dashes

# Heading 1
Test content

---

# Heading 2
I am hidden heading and can't be seen in the Preview

---

# Heading 3

Next steps

  • Speaker notes support; hiding those from preview
  • More cleanup

Maybe I will soon release the first version of the plugin :slight_smile:

Great to hear it worked!
Can’t wait to try it :wink:

Okay, now the first version is released as v0.1.0 :tada:

https://my.inkdrop.app/plugins/reveal-md-presenter

It seems that I will need to link the screenshots differently as now the plugins page does not understand to look from the correct place.

1 Like

Congrats, it worked!

I guess it’d be nice to have an instruction about how to use it?
Because I didn’t know I have to run reveal-md manually by copying the command from menu.

I fixed the screenshots not showing on the plugin page!
Great work, Sami!!

1 Like

Thanks for testing! :blush:

Yes, I will need to improve the instructions.
I tried to put all the required info to the Help-menu, but would be nice also to have it on the README.

p.s Thanks also for fixing the screenshots!

Currently doing some improvements to this plugin for easier using.

I haven’t figured how I should detect it when Inkdrop has saved changes to current file when pressing Cmd+S. Or is it currently possible to do that?

I am not exactly sure whether this command fires on Cmd+S, but I guess it’s worth a shot to try the core:save-note command:

const disposable = inkdrop.commands.add(document.body, {
  'core:save-note': () => {
    // Do something
  },
});
3 Likes

Thanks a lot Jasper, it did the trick!

Didn’t know that it could be used like that to be listened. I understood from the documentation that they were only possible to be “sent”, so that in this case that I would tell for Inkdrop to save the note.

1 Like