code-input icon indicating copy to clipboard operation
code-input copied to clipboard

Selecting a specific language with the autodetect plugin

Open nikita51bot opened this issue 1 year ago • 4 comments

Hi, I'm just getting started with code-input and I have a question, how can I select a specific language when the autodetect plugin is registered?

    <script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js"></script>
    <link rel="stylesheet"
        href="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/default.min.css">
    </link>

    <script src="https://cdn.jsdelivr.net/gh/WebCoder49/[email protected]/code-input.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/WebCoder49/[email protected]/code-input.min.css">

    <script src="https://cdn.jsdelivr.net/gh/WebCoder49/[email protected]/plugins/autodetect.min.js"></script>
        

    <script>
        codeInput.registerTemplate("syntax-highlighted",
            codeInput.templates.hljs(
                hljs,
                [
                    new codeInput.plugins.Autodetect(),
                ]
            )
        );
    </script>

I've tried adding the tag language="HTML" to the code-input block, but it automatically changes to the language the plugin has defined. Thanks in advance for the answer!

nikita51bot avatar Nov 03 '24 19:11 nikita51bot

I'm afraid I didn't design the autodetect plugin with this in mind but it definitely should be an option. I am very busy at the moment (please see my GitHub status) but will let you know here when I start to work on it.

WebCoder49 avatar Nov 04 '24 16:11 WebCoder49

@nikita51bot, I'm assuming you want to be able to disable the autodetection and reset the language sometimes, but keep autodetection other times. The fix I am currently developing will therefore let you remove the autodetect plugin from a code-input element and add it again when you want. Is this what you need?

(Sorry for the delay; I am busy but found a short break now)

WebCoder49 avatar Feb 18 '25 13:02 WebCoder49

Yes, I want that when the user purposefully specifies a programming language, it will not change when typing the text

nikita51bot avatar Feb 27 '25 12:02 nikita51bot

Progress

@nikita51bot Hi, and sorry for the long delay. I did start implementing this as well as more general-purpose plugin addition/removal which this is part of, but overestimated the time I had available, became very busy, and only just pushed my work in progress to the autodetect-override branch now. Anyone else who has spare time is welcome to continue/complete it.

I've given untested code that may work below; please try it. An indication of how urgent your need for this feature is would be helpful, too.

Workaround

Right now, you can hack the autodetect plugin (i.e. copy and paste its code into a new file then load it as usual) to turn it on/off on demand by calling a method of it; this isn't as reusable as my foreseen solution but is much quicker to implement:

/**
 * Autodetect the language live and change the `lang` attribute using the syntax highlighter's 
 * autodetect capabilities. Works with highlight.js only.
 * Files: autodetect.js
 */
codeInput.plugins.Autodetect = class extends codeInput.Plugin {
    currentlyAutodetecting = false;
    constructor() {
        super([]); // No observed attributes
    }
    /* Remove previous language class */
    beforeHighlight(codeInput) {
        if(this.currentlyAutodetecting) {
            let resultElement = codeInput.codeElement;
            resultElement.className = ""; // CODE
            resultElement.parentElement.className = ""; // PRE
        }
    }
    /* Get new language class and set `language` attribute */
    afterHighlight(codeInput) {
        if(this.currentlyAutodetecting) {
            let langClass = codeInput.codeElement.className || codeInput.preElement.className;
            let lang = langClass.match(/lang(\w|-)*/i)[0]; // Get word starting with lang...; Get outer bracket
            lang = lang.split("-")[1];
            if(lang == "undefined") {
                codeInput.removeAttribute("language");
                codeInput.removeAttribute("lang");
            } else {
                codeInput.setAttribute("language", lang);
            }
        }
    }
    turnOn() {
         this.currentlyAutodetecting = true;
    }
    turnOff() {
         this.currentlyAutodetecting = false;
    }
}

Please bear in mind I haven't tested the above code, but do respond if you're not sure how to use it.

My current status:

I'm afraid I'm very busy right now until 21 June. I can't implement new feature requests in projects I maintain, but can merge contributions by others, especially if they fix bugs.

WebCoder49 avatar May 10 '25 11:05 WebCoder49