简体   繁体   中英

How can I add linenums dynamically to Google Code prettify?

I have this fiddle . I am trying to format some code and am having trouble inserting and removing line numbers dynamically. It seems on the first page load the line numbers appear but once I click run then I can't get them back. On my website they don't show at all. I would like to let users click a button and turn on/off the line numbers dynamically:

<body>
  <pre id="pre">
    &lt;script type=&quot;text/javascript&quot;&gt;
    // Say hello world until the user starts questioning
    // the meaningfulness of their existence.
    function helloWorld(world) {
      for (var i = 42; --i &gt;= 0;) {
        alert('Hello ' + String(world));
      }
    }
    &lt;/script&gt;
    &lt;style&gt;
    p { color: pink }
    b { color: blue }
    u { color: &quot;umber&quot; }
    &lt;/style&gt;
</pre>


<button id="button">My button</button>
</body>

$(document).ready(function(){
  $("#button").on("click", function(){
         $("#pre").addClass("prettyprint").addClass("linenums").addClass("lang-js");
     $("#pre").html(PR.prettyPrintOne($("#pre").html()));
  });
});

Thanks!

EDIT: Note that this is different than How to add line numbers to all lines in Google Prettify? . In mine, the line numbers show up at first if I add linenums class to the pre tag manually. Problem is turning them on/off with jquery doesn't work.

By calling prettyPrintOne you're essentially circumventing the class based initialisation. That method has arguments that tell prettify how to behave.

You're trying to modify how prettify behaves with classes but prettify ignores that because it only cares about the arguments which are null, therefore they fallback to internal defaults.

See the source documenting the method:

    /**
     * Pretty print a chunk of code.
     * @param {string} sourceCodeHtml The HTML to pretty print.
     * @param {string} opt_langExtension The language name to use.
     *     Typically, a filename extension like 'cpp' or 'java'.
     * @param {number|boolean} opt_numberLines True to number lines,
     *     or the 1-indexed number of the first line in sourceCodeHtml.
     * @return {string} code as html, but prettier
     */

prettyPrintOne is essentially for parsing some code passed to it as a string, and returning the result, with the options controlled by those arguments. Conversely prettyPrint will traverse the DOM looking for the classes you're adding, behaving according to the classes it finds. As you want to toggle, you'll want to keep using prettyPrintOne so that we can have control of when to show prettified output, and when to show the original - more on that later.

As an aside, you're telling prettify to format JS when what you've got there is HTML including JS in script tags and CSS in style tags. So you'll want to use HTML as the lang extension, not JS.

Anyway, all you need to do is adjust your call to the below, additionally adding the prettify class solely so your prettify theme CSS applies:

$("#pre").html( PR.prettyPrintOne($("#pre").html(), "html", true) )
    .addClass("prettyprint");

Et voila:

显示行号

As for toggling, you just need to adjust the logic so that you store the original HTML somewhere on prettify-ing and restore it next time the button is clicked:

  $("#button").on("click", function() {
    // Cache jquery object
    var $pre = $("#pre");
    // If the element has a prettyprint class, it's already been manually
    // prettified
    if (!$pre.hasClass("prettyprint")) {
      // Element hasn't been prettified, store the html in jQuery data
      $pre.data("original-html", $pre.html());
      // Manually prettify
      $pre.html(PR.prettyPrintOne($pre.html(), "html", true))
        .addClass("prettyprint");
    } else {
      // Element has been prettified, restore the orginal html stored in jQuery
      // data and remove the prettyprint class, back to where we started
      $pre.html($pre.data("original-html"))
        .removeClass("prettyprint");
      // Remove the jQuery data entry for our original HTML, so next time we
      // start fresh
      $pre.data("original-html", null);
    }
  });

Here's a jsfiddle showing that in action: https://jsfiddle.net/joshdavenport/68thqus1/27/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM