Skip to content
This repository has been archived by the owner on Dec 30, 2023. It is now read-only.

Make the Markdown presentations fancier when being shown #26

Merged
merged 41 commits into from
Oct 27, 2020
Merged

Make the Markdown presentations fancier when being shown #26

merged 41 commits into from
Oct 27, 2020

Conversation

PhilRunninger
Copy link
Contributor

@PhilRunninger PhilRunninger commented Oct 9, 2020

There is a lot to unpack in this one. I wanted to make my presentations a bit spiffier, as if rendered to HTML. Of course, we're limited by what we can do with mono-spaced characters in a Vim buffer. So here's what I did.

Markdown-specific Changes

  1. Only # and ## headings are used as slide separators now.
  2. #, ##, and ### headings are replaced by the output of the program figlet, if it's installed and g:presenting_figlets is 1. The fonts for both large and small headings can be overridden by the user.
  3. #, ##, ###, and #### headings are centered in the window. This at least partially addresses Center slide content #22.
  4. Bullets are replaced by the Unicode bullet operator:
  5. Numbered lists are autonumbered, and respect the original indentation.
  6. Github-flavored Markdown's checkboxes are rendered with respective Unicode characters: and
  7. Github-flavored Markdown's tables are rendered with box drawing characters. Some special considerations need to be observed with tables.
  8. Quote blocks are word-wrapped and have a left border:
  9. Code blocks are preceded and followed by a horizontal line:
  10. Comments can be added to slides. Lines starting with // will not be displayed when presenting.
  11. Markdown syntax highlighting is extended to highlight the new text described above.

Here is an animated GIF showing the changes. It is also embedded in the README.

FancyMarkdown

General Changes

  1. The keys used to advance, rewind, and quit a slide show are now configurable.
  2. Default slide separator regex strings are set in filetype plugin files (ftplugin/*.vim) as opposed to autocommands. This puts the code in a location that better matches its purpose. If additional statements are needed, they fit better in these files than in an autocommand.
  3. A standard, extendable framework is introduced in the form of the s:Format() function and the related autoload/markdown.vim file. Following the pattern set forth therein, custom formatting can be implemented for other filetypes as well. For example, to enable custom formatting for RST files, do the following:
    1. Write the function rst#format(text, state) in the new file autoload/rst.vim. This function takes the current line of text and a state dictionary that describes the current state of the process. state can be used to remember such things as "We're inside a code block," which would change how the current text is formatted. An updated state is returned by this function, and is passed back in for the next line of text.
    2. If custom syntax highlighting is desired, create the file syntax/presenting_rst.vim, and include the appropriate syntax and highlight commands in it.

Using the get() function makes the assigning of defaults to global
variables a simple one-liner instead of an if block for each one.
It will call an autoload function defined for each file type, which
formats one line at a time. State information, which may be needed to
format one line based on previous lines, is maintained and passed into
the file-specific autoload function.

To implement this for a filetype, foo for example, create a file named
autoload/foo.vim, and write a function with the signature:
  foo#format(text, state)
Its return value is a 2-item list consisting of:
  1. a list of 1 or more strings to be added to the replacement slide
  2. the new value of state
Its capabilities are:
  #, ##, ### lines are rendered using the figlet program if installed.
  #, ##, ###, #### lines are centered in the window.
  - and * list indicators are replaced with a Unicode bullet operator.
  Numbers are recalculated in numbered lists, respecting indents.
  - [ ] and - [x] are rendered with unchecked and checked Unicode boxes.
  Code blocks are surrounded by horizontal lines.
  Quote blocks are word wrapped, indented, and have a left border.
The slides produced from markdown files no longer follow markdown syntax
rules. There needs to be some way to specify an alternate syntax file
for these slides. If a ...#set_filetype() function is implemented in the
filetype's autoload module, then it will be used to set the filetype of
the slide show; otherwise, the original source file's type will be used.

This works out nicely because (for now) markdown is the only filetype
that implements this. If a different filetype is used as source for the
slides, it will continue with its current behavior, setting the slide
show's filetype to the same as its source file's.
The ftplugin files makes it easier to do multiple setup commands should
any more become necessary.
Use an autocommand to toggle the tabline when moving in and out of the
slideshow buffers. Using `setlocal showtabline=0` doesn't work because
it's not a local setting.
If you choose to set <Esc> to be the quit key, and <Left> to be the
previous slide key, you will experience very odd behavior related to the
way Vim processes "grey keys". If you press <Left> to go back a slide,
the terminal sends <Esc>[D. When Vim gets this sequence, it sees that
<Esc> has been remapped, and does that (quit the slide show) instead.
Then it continues with [D, and causes all kinds of havoc in the current
buffer. The problem and a solution is described in this StackOverflow
discussion: https://stackoverflow.com/a/20458579/510067
We can achieve the same thing with the execute command, and reduce the
implementation requirements for future filetypes.
Allow it to return either a string, or a list of strings. s:Format()
will figure out how to handle it.
@PhilRunninger
Copy link
Contributor Author

@sotte , I've heard it said that software is never finished; it's just released. With that in mind, I made a few changes after creating the pull request, but I'm done now. Go ahead and merge this if you approve it.

@sotte
Copy link
Owner

sotte commented Oct 10, 2020

Wow @PhilRunninger, this is quite the PR! Thank you and I'm glad you're enjoying the presenting.vim. Also thanks for the small commits with proper commit messages! I'll try to review it this weekend.

Can you please add some screenshots to the PR showing off the new features especially figlet.

I'm thinking of re-recording the asciicast in the README.

`set filetype=<something>` always works, even if there is no such file:
`syntax/something.vim`, so the try-catch block was useless. Switch to an
if block instead, looking for the syntax file in the runtime path.
@PhilRunninger
Copy link
Contributor Author

@sotte, I created an animated GIF of the new Markdown formatting. It is embedded in the README and (now) in the PR description.

@sotte
Copy link
Owner

sotte commented Oct 10, 2020

Thank you so much. This is a really nice feature, I'm impressed!

I also like the attention to detail ;)

Tables are a Github-flavored extension to Markdown. To be used by this
plugin, they must be defined with vertical bars at the beginning and end
of the line. This macro doesn't do any spacing adjustments, except for
centering the whole table, so the user will need to align the columns
manually in the Markdown file.
@sotte
Copy link
Owner

sotte commented Oct 24, 2020

I'm trying it out now. Do you plan to add any more features to this PR or is it feature complete? @PhilRunninger

@sotte
Copy link
Owner

sotte commented Oct 24, 2020

I don't get any of the cool new features. I think vimwiki (when using markdown) collides with presenting.vim. Debugging...

@sotte
Copy link
Owner

sotte commented Oct 24, 2020

Yes, it was vimwiki. Without vimwiki I get the new features. But I still have some issues with figlet.

image

@PhilRunninger
Copy link
Contributor Author

I'm done with this PR. If I think of anything else, I'll create another one.

My Mac installation of figlet includes the figlist command which shows all the installed figlet fonts. Alternatively you can try figlet -I 2 to display the folder where fonts are installed. You can then specify a different font by putting, for example, let g:presenting_font_small = 'mini' in your .vimrc.

@sotte
Copy link
Owner

sotte commented Oct 24, 2020

Hey @PhilRunninger, thanks for the quick response and the help!

Two things:

  • Please add a section "Known issues" to the README and the docs and mention that presenting.vim and vimwiki are not playing well together

  • Please change straight figlet font to something else. straight is not available on Ubuntu by default. We should pick a font that is available on many platforms. Here is a list of the available ones on Ubuntu.

Default font: standard                                                                        
Font directory: /usr/share/figlet                                                             
Figlet fonts in this directory:                                                               
banner                                                                                        
big                                                                                           
block                                                                                         
bubble                                                                                        
digital                                                                                       
ivrit                                                                                         
lean                                                                                          
mini                                                                                          
mnemonic                                                                                      
script                                                                                        
shadow                                                                                        
slant                                                                                         
small                                                                                         
smscript
smshadow
smslant
standard
term

After that I'll merge it.

The Ubuntu installation of figlet does not ship with the font
"straight". It's best replacement is "mini", but because it's a little
harder to read than the blocky fonts, I switch to "standard" for the
large # headings, and "small" for the smaller ## and ### headings.
If installed, vimwiki will take control of Markdown files, and change
their filetype to vimwiki. When presenting such a file, presenting.vim
will try to find a syntax file named "presenting_vimwiki.vim". It won't
find such a file, and will resort to the original filetype "vimwiki" for
syntax highlighting. This doesn't have all the nice syntax highlighting
features that "presenting_markdown.vim" provides.

So to prevent that hijacking, we just need to look for a filetype of
"vimwiki", and change it to "markdown" when starting the slide show.
@PhilRunninger
Copy link
Contributor Author

@sotte I'll do you one better on that vimwiki issue. I added a simple check for the vimwiki filetype, and changed that back to markdown when preparing the slide show.

The more direct replacement for straight would have been mini, but I decided that I like the blocky fonts better, so I picked standard and small for the defaults.

@sotte
Copy link
Owner

sotte commented Oct 27, 2020

@PhilRunninger great feature and great commits!
I'm excited to use it for my next presentation.

Thank you so much!

@sotte sotte merged commit 9545682 into sotte:master Oct 27, 2020
@PhilRunninger
Copy link
Contributor Author

My pleasure. I'm interested to see if anyone else implements this custom formatting for the other file types.

@sotte
Copy link
Owner

sotte commented Oct 27, 2020

Me too. I created a ticket for it: #27

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants