PrismJS / prism

Lightweight, robust, elegant syntax highlighting.
https://prismjs.com
MIT License
12.14k stars 1.28k forks source link

Support for simplified or alternative theme for inline code than for block (a la Slack's single- vs. triple-backtick) #3347

Open UInIQ opened 2 years ago

UInIQ commented 2 years ago

Motivation Typically, I find myself making reference to code in two different ways: sometimes inline code references makes sense within the flow of a block of text (like if I make reference to setting display:flex; I don't necessarily want the full-blown background-color/text-shadow/font/font-size change... just the foreground reserved word/syntax coloring portions. I don't want my font/line height/element display renderer changing necessarily.

image

vs

image

(except... yanno... with syntax highlighting?) By virtue of the fact that the background color would be shifting from a dark to a light one precludes a simple css override. That white foreground text is gonna be hard to read atop a white page background.

Description I'd like to be able to specify a reduced ruleset, stylesheet, and/or theme specification for mid-paragraph <code>that appears within an inline</code> tag, vs. a dedicated

<pre><code>block in which I'm expecting to give the whole block-level element to the endeavor</cod></pre>
image

Alternatives Well, since I cannot fathom I'm the first person to ask for this in the decade Prism's been in use, I'm kinda hoping I'm just missing something blatant in the API docs and someone will say, "here, moron!"

Notwithstanding that, My next intention will be to define a high-specificity style override comprised of a CSS reset followed with what amounts to a secondary redefinition of the styles I want being left alone (this is the main reason I'm trying to avoid this approach; DRY it s not). But, I mean, let's face it: Prism enforces certain tag structures. This suggests that the selector code is already fairly-well scoped (I confess I've not dug through your codebase yet).

Assuming that's doable without too much overhead, it seems like it should be little enough effort (assume the aforementioned presupposition regarding selector scoping is true) to either add some exclusionary code to the DOMContentReady event such that it applies one of multiple themes its found defined in some global constant or conditional rule being set at the :root scope, or, failing that, to arbitrarily set some selector conditional to the application of the style code it has now (span.inline>pre:first-child:last-child>code or somesuch), to only perform the override when the specified code is the only child inside an inline tag with a class of inline or similar.

Please understand: I'm not rolling up here to just make demands like some entitled dick. I work in the same OS spaces y'all do, and I know exactly how much thankless work goes into maintaining tools like these. If there really is no fix for this or provision in place for the functionality, I'll go beat on it with a hammer myself until I get it rolling, and then open a PR. I'm just hoping this is simply obliviousness on my part. I did observe the long-closed Issues 643 and 807, but neither really seemed to be asking after the same thing, nor did either really receive an official solution, and both were closed while Obama was still president. A lot "could have" changed, lol.

RunDevelopment commented 2 years ago

I cannot fathom I'm the first person to ask for this

You are, at least since I started working on this project.

That being said, it's not that difficult to do, at least by modifying the theme you're using.

None of our themes support what you want to do. While themes are able (and are free) to implement the style you're going for, none of them have (supposedly because their authors didn't want to or didn't think it was necessary). However, it's not hard to change any existing theme to support your wanted style.

Modifying

Firstly, I assume that you have full control over the CSS of your target Prism theme and some familiarity with CSS. You can find the CSS of all themes here. For more themes, see here.

All themes follow a structure like this:

/* styles shared between code blocks and inline code */
/* (optional) styles specific to code blocks */
/* (optional) styles specific to inline code */
/* styles specific for tokens */
/* (optional) overrides for plugin styles that affect code blocks */

Generally speaking about CSS selectors:

This information should be enough for you to split the styles of a theme between code blocks and inline code.

You seem to be using Dark, so here is how that would look like for Dark. Note: I'm using SCSS because all selectors have to be prefixed with either pre > code or :not(pre) > code to make them code block or inline code specific.

/* shared styles */
code[class*="language-"],
pre[class*="language-"] {
    color: white;
    background: none;
    text-shadow: 0 -.1em .2em black;
    font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
    font-size: 1em;
    text-align: left;
    white-space: pre;
    word-spacing: normal;
    word-break: normal;
    word-wrap: normal;
    line-height: 1.5;

    -moz-tab-size: 4;
    -o-tab-size: 4;
    tab-size: 4;

    -webkit-hyphens: none;
    -moz-hyphens: none;
    -ms-hyphens: none;
    hyphens: none;

    @media print {
        text-shadow: none;
    }
}

/* code blocks */
pre > code {
    padding: 1em;
    margin: .5em 0;
    overflow: auto;
    background: hsl(30, 20%, 25%);
    border: .3em solid hsl(30, 20%, 40%);
    border-radius: .5em;
    box-shadow: 1px 1px .5em black inset;

    /* all token styles */
}

/* inline code */
:not(pre) > code {
    padding: .15em .2em .05em;
    border-radius: .3em;
    background: hsl(30, 20%, 25%);
    border: .13em solid hsl(30, 20%, 40%);
    box-shadow: 1px 1px .3em -.1em black inset;
    white-space: normal;

    /* all token styles */
}
varelycode commented 1 year ago

It would be nice to have this feature. I often do wish I could do inline blocks but a quick solution is to use the single line code tag and set the style="display:inline"