Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mega Enhancement: Syntax Highlighting #164

Open
sbrl opened this issue Jan 29, 2019 · 5 comments
Open

Mega Enhancement: Syntax Highlighting #164

sbrl opened this issue Jan 29, 2019 · 5 comments
Labels
Area: Code It's got something to do with code enhancement Let's make it better!

Comments

@sbrl
Copy link
Owner

sbrl commented Jan 29, 2019

It sounds simple on the surface, but syntax highlighting is proving to be a really thorny issue. The trick is going to be to do it whilst maintaining the following principles of Pepperminty Wiki:

  1. Everything is in a single file
  2. Be compatible with a reasonable number of different web servers & environment setups (though this does not include old PHP versions!)
  3. No additional installation steps required (or a done transparently on first load - e.g. creation of peppermint.json, pageindex.json, etc.)

Initially, I thought that utilising a phar would be a great idea - because we can have our own internal file structure - but present a single file!

Unfortunately, this comes with a bit of a caveat: It requires the .phar extension - which isn't usually configured on web servers - breaking point #2.

After about 15 minutes of head-scratching, I've managed to remember the name of a very special PHP function that halts the PHP processor, allowing arbitrary data to be embedded at the end of the file: __halt_compiler();. We could pack up our extra dependencies into a compressed archive (zip? .tar.gz? .tar.bz2? we'll have to see what's available).

There are other questions too:

  • Do we want to do the highlighting server-side or client-side?
  • How do we do this in a manner that makes it accessible to any module?
    - We can use the current build system to expose a property in the array that's passed to register_module that lets modules specify files to embed & unpack on first run - the build system does actually require() each module during the build process to build a JSON index file that's used by the packing script. I should probably document this process.
    - Perhaps we can download & pack Parsedown etc. here to avoid a first-run download too?

Definitely something to mull over.

@sbrl sbrl added enhancement Let's make it better! Area: Code It's got something to do with code labels Jan 29, 2019
@sbrl
Copy link
Owner Author

sbrl commented Jan 29, 2019

If we did it server-side, we'd want to use a composer package. luminous looks good, but it's slow apparently - and has a caching system built-in. We'd probably want to cache the output of the currently selected parser here in some fashion in order to use this method.

If we did it client-side, I'd love to be able to use prism.js. We'll have to figure out how to use the web-based downloader on the command-line though and specify the plugins we want.

@sbrl
Copy link
Owner Author

sbrl commented Feb 26, 2019

We've implemented a cache system (and fixed a nasty bug in #165). Now that v0.18 is out, I think it's time to think about refactoring the downloading system to enable us to work on the server-side syntax highlighting.

It's probably worth noting that although this will allow us to bundle all sorts of extra files with Pepperminty Wiki, the intention here is to avoid using it except when we really need to. In other words, this won't be for packing multi-file modules etc - only for essential libraries that are needed to perform a function. Good examples of things include:

  • Parsedown / ParsedownExtra / ParsedownExtreme
  • Luminous
  • JSDiff

The intention here is to keep Pepperminty Wiki targeted at what it's good at: setting up a new small wiki really quickly - and avoid what we can't possibly hope to compete with (i.e. the full power of MediaWiki). Pepperminty Wiki is small, fast, and light. It's not without any bells and whistles though - we just need to be selective in the ones that we include :P

@sbrl
Copy link
Owner Author

sbrl commented Feb 26, 2019

Looks like this rework it more urgent than I thought. RawGit, the mechanism we use to download Parsedown, is shutting down in October this year. To this end, I'd like to move away from the current system of downloading files from RawGit to a system on unpacking from index.php and make a stable release before October 2019.

We should open a separate issue for this.

@sbrl
Copy link
Owner Author

sbrl commented Aug 5, 2019

We've got our new packaging system, so now we can consider adding syntax highlighting.

Luminous looks good - maybe we could use that?

@ElDani82
Copy link

ElDani82 commented May 1, 2023

Hey there. I stumbled over Pepperminty Wiki earlier today, because I was looking for a self-hosted but public (thus web-based) note-taking application that would support the markdown language and this seemed like a simple and easy thing to use.

But on to this issue: I'm not sure about the project's stance toward the use of first vs third-party resources, but it's trivially easy to implement code highlighting on the client side. I've created a proof of concept in form of a userscript, which uses the javascript library highlight.js:

image

// ==UserScript==
// @name         Pepperminty Wiki - Syntax Highlighting
// @description  Adds client-side syntax highlighting to a Pepperminty Wiki instance
// @namespace    pepperminty-eldani
// @author       eldani
// @version      1.0
// @match        *://192.168.0.155/pepperminty-wiki/*
// @resource     CSS_LIGHT https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/styles/default.min.css
// @resource     CSS_DARK https://raw.githubusercontent.com/dracula/highlightjs/master/dracula.css
// @require      https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/highlight.min.js
// @grant        unsafeWindow
// @grant        GM_getResourceText
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    const use_dark_theme = window?.matchMedia('(prefers-color-scheme: dark)')?.matches || false;
    GM_addStyle(
        GM_getResourceText(use_dark_theme ? "CSS_DARK" : "CSS_LIGHT")
    );
    unsafeWindow.document.querySelectorAll("pre code").forEach((el) => {
        el.className.startsWith("language-")
        ? hljs.highlightElement(el)
        : el.className = "hljs";
    });

})();

Ignore the theme detection; it works for me, because I use the Blue theme and the Dark Reader extension.

If this were to be integrated as-is into the wiki, it would increase the size of the single .php file by 123 KB (121 KB of which is minified javascript code).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Code It's got something to do with code enhancement Let's make it better!
Projects
None yet
Development

No branches or pull requests

2 participants