www.webdeveloper.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 34

Thread: Javascript to format Arduino code

  1. #16
    Join Date
    May 2014
    Posts
    892
    Quote Originally Posted by pedro147 View Post
    just as you said Too easy
    Too often these days people are writing JS where the HTML hooks the scripting instead of the other way around, or that you have to target by specific Id's in the scripting. I like making my scripts target the markup instead -- since then the page can gracefully degrade scripting off. It's also nice as it means you can have more than one block on the page formatted.

    Quote Originally Posted by pedro147 View Post
    What does your zoot project do?
    It's a wind controller akin to the Akai EWI. I have my own website about the USB version:

    http://www.ewiusb.com/

    It's basically an electronic woodwind. You blow into it and a pressure sensor is translated into midi controller data. The keys are capacitive touch sensitive (so no moving parts -- like a touch lamp). The fancy non-usb models have 8 octave rollers giving you a ridiculous possible 10 octaves, the USB model has 3 rollers resulting in a five octave range. The result of all the inputs is turned into a MIDI data stream.

    There were a number of things I wish the EWI USB had that it's more expensive counterparts do -- like an actual display to tell you what's going on, the ability to do things like setting the instrument key, and so forth -- and a few things I think would be nice like the ability to output major and minor chords with each note on a different MIDI channel. (so each one could be assigned a different voice)... which is where my attempts to build my own version come into play.

    The one from Akai also has some physical issues I'm trying to address like being difficult to just 'hold on to' -- which is why I was thinking that maybe it should just have a velcro strap around the right hand like a camcorder. Or that the USB plug and wire comes straight out the bottom in a manner that you really shouldn't rest it on it's end, or you'll stress the cord.

    Originally I wanted to build it with a normal arduino, but it just didn't have enough oomph or pinouts. A Teensy++ proved much more effective particularly since they have optimized I/O writes and reads in it's version of the Arduino interface, but I was still resorting to a bit more machine language than I'd have liked, and it's not QUITE as responsive as I'd like when you have more than two-thirds the keys touched. I figure if I was right on the edge of perfection with the Teensy++, the 40mhz Arm3 in the Teensy 3.0 should be overkill...

    The cool thing about the Teensy 3.0 being that it might be an entirely different CPU family, but it will run most Arduino Sketches.

    The software from Akai and Garritan is... meh. But you combine it with some good software like Sample Modeling's "The Saxophones" and it's a whole different beastie.

    See this fellow playing the EWI 4000s with the Mr. Sax T softsynth from "The Saxophones"
    https://www.youtube.com/watch?v=KIGXcMZ0WnE

    Or Bernie Kenerson with the EWI USB and the Mr. Sax B softsynth:
    https://www.youtube.com/watch?v=Y6bWKpF10NQ

    Basically, the end result is not what comes to mind for most people when they think MIDI.

    I used to be a Tenor and Bari sax player, but a few years ago some quacks screwed up and over/mis-medicated me right into a slew of problems including a mild parkinsonism and neurological damage that makes it hard for me to press the keys on a real sax -- The EWI being touch sensitive instead of having buttons you press means I still get to play, instead of having my muse stifled.

    ... and yet I'm STILL a model M elitist jacktard when it comes to computer keyboards.

    It's also nice as I can't afford a new Bari (a cheap one is five grand, a good one is the cost of a car) -- while the getting a EWI USB and "The Sax Brothers" works out to the same outlay as a cheap chinese e-bay alto sax (well under a grand).

    Though I've wanted to build one since I saw this performance live when I was a teenager in the '80's... When my crappy little high school quartet (Frayed Edges) was on a opposite stage.
    https://www.youtube.com/watch?v=b6_iI5DgL7Q
    Last edited by deathshadow; 07-21-2014 at 05:36 AM.
    Java is to JavaScript as Ham is to Hamburger.

  2. #17
    Join Date
    Dec 2005
    Location
    FL
    Posts
    7,377

    Arrow

    Quote Originally Posted by pedro147 View Post
    JMRKER - I got your script to work on my site page at http://www.pedrosdigitalsolutions.co...20Arduino.html
    but I am trying to replace only whole words. However the script is affecting the 'if' in the word 'shiftIt'. How might I modify the script to stop this please. Fiddle http://jsfiddle.net/MVpyb/embedded/result/
    I know you already have a solution from 'DeathShadow',
    but only for completeness of your question, here is an answer.

    Note: It does require a bit of consistency in the formatting of your statements.
    For example, it will not recognize 'if(' but does highlight correctly 'if ('
    and 'for(' is not highlighted correctly unless typed 'for ('
    Also 'shiftit(' does display correctly regardless of the case of the letters (upper-case or lower-case)
    because there is no testing of the case of the letters in the replace function.

    I would stick with 'DeathShadow's code unless it is too difficult to decipher.
    Until then you could use mine as a backup as you study and learn from his/her code.
    Good Luck!


    Whoops. Forgot to include code change...
    Code:
    <!DOCTYPE HTML>
    <html>
    <head>
    <title>pedroduino.com</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link type="image/x-icon" href="/custom pd/images/arduino.ico" rel="shortcut icon">
    <link media="screen" type="text/css" href="style.css" rel="stylesheet">
    
    <style type="text/css" media="all">
     .thewordBlue { color:#006699; }
     .thewordRed { color:#CC6600; }
     .thewordLogic { color:green; }
    
     .textInfo { position:absolute; top:40px; left:140px; }
     .scrollBox {
      position:absolute; top:150px; left:92px; border:1px solid #33CC33;
      background-color:#F6F6E3; width:850px; height:480px; padding:0 30px;
      overflow-y:scroll; overflow-x:scroll;
     }
    </style>
    
    </head>
    <body>
    <div id="content" style="height:1000px;">
    <!--CONTENT GOES HERE-->
     <div class="textInfo">
      <br>This is some text int that may contain void loop some full or partial void keywords that I do not want the js replace script to change
      <p><pre>int char void setup pinMode void loop for digitalWrite else delay HIGH LOW OUTPUT</pre>
     </div>
    
    <!--POSITION SCROLL BOX-->
     <div class="scrollBox">
      <p style="width:250%;">
       <pre id="preText">  <!-- ARDUINO CODE -->
    
    ***************************************************************************
    
    // 7-SEGMENT LED COUNTER, MULTIPLEXING USING 74HC595 8-BIT SHIFT REGISTER,
    // INCREMENT COUNTER ZERO TO NINE TO ZERO VIA POTENTIOMETER
    // Code mangled together from these sources - thanks fellas
    // http://www.sweeting.org/mark/blog/20...nt-led-display
    // http://thecustomgeek.com/2011/06/29/...-a-7-year-old/
    // http://nootropicdesign.com/projectla.../25/led-clock/
    const int latchPin = 5; // PIN CONNECTED TO PIN 12 OF 74HC595 (LATCH)
    const int dataPin = 6; // PIN CONNECTED TO PIN 14 OF 74HC595 (DATA)
    const int clockPin = 7; // PIN CONNECTED TO PIN 11 OF 74HC595 (CLOCK)
    int counter = 0; // INITIALISE COUNTER AS ZERO
    int potReading = 0;
    // DESCRIBE EACH DIGIT IN TERMS OF DISPLAY SEGMENTS 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
    const byte numbers[10] = 
    {
      B11111100,
      B01100000,
      B11011010,
      B11110010,
      B01100110,
      B10110110,
      B10111110,
      B11100000,
      B11111110,
      B11100110,
    };
    void setup() {
      pinMode(latchPin, OUTPUT); // SET SR PINS TO output
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
    }
    void loop() {
      potReading = analogRead (A0);
      potReading = map(potReading, 0, 1023, 0, 8);
      {
        if (potReading > 8) potReading --;
        show(numbers[potReading]);
      }
      {
        if (potReading < 0) potReading ++;
        show(numbers[potReading]);
      }
    }
    void show( byte number) {
    // USE A LOOP AND A BITWISE AND TO MOVE OVER EACH BIT THAT MAKES UP
    // THE SEVEN SEGMENT DISPLAY (FROM LEFT TO RIGHT, A => G), AND CHECK
    // TO SEE IF IT SHOULD BE ON OR NOT
      for (int j = 0; j <= 7; j++) {
        byte toWrite = number & (B10000000 >> j);
        if (!toWrite) { continue; } // IF ALL BITS ARE 0 THEN NO POINT WRITING IT TO THE SHIFT REGISTER,SO BREAK OUT AND MOVE ON TO NEXT SEGMENT.
        shiftIt(toWrite); // OTHERWISE SHIFT IT INTO THE REGISTER
      }
    }
    void shiftIt (byte data) {
      digitalWrite(latchPin, LOW); // SET latchPin Low WHILE CLOCKING THESE 8 BITS IN TO THE REGISTER
      for (int k=0; k <= 7; k++) {
        digitalWrite(clockPin, LOW); // CLOCKPIN Low PRIOR TO SENDING A BIT
    // NOTE THAT IN OUR CASE, WE NEED TO SET PINSTATE TO 0 (Low) FOR
    // “ON” AS THE 74HC595 IS SINKING CURRENT WHEN USING A COMMON
    // ANODE DISPLAY. IF YOU WANT TO USE A COMMON CATHODE DISPLAY THEN
    // SWITCH THIS AROUND.
    
        if ( data & (1 << k) ) {
          digitalWrite(dataPin, HIGH); // TURN"ON"
        } else {
          digitalWrite(dataPin, LOW); // TURN "OFF"
        }
      digitalWrite(clockPin, HIGH); // AND CLOCK THE BIT IN
      }
      digitalWrite(clockPin, LOW); // STOP SHIFTING OUT DATA
      digitalWrite(latchPin, HIGH); // SET latchPin TO High TO LOCK AND SEND DATA
    }
       </pre>
    
    // demonstration of a DIFFERENT code block
       <pre id="postText">
    void displayLogicCode (byte info) {  // Non-sense code for_display DEMO ONLY
      shiftit(info);  
      switch (info) {
        case 0: shiftit(info); break;
        case 0: shiftit(info * 2); break;
        case 0: shiftit(info * 4); break;
        default: break;  // do nothing
      }
    }
       </pre>
    
      </p>
     </div>
    <!--CLOSE STYLE DIV FOR SCROLL BOX-->
    </div> <!-- CONTENT ENDS HERE -->
    
    <script type="text/javascript">
    function highlightArduinoCode(IDS) {
      var preText = document.getElementById(IDS).innerHTML;
      var logicWords = ['if ','else ', 'switch ','case ','break;']; 
      var redWords = ['int ','char ','void ','setup ','pinMode','for ','loop;',
                     'digitalWrite','digitalRead','delay','byte ','const ']
      var blueWords = ['HIGH','LOW','OUTPUT'];
      var re, word, replacement;
    
      for (var i=0; i<redWords.length; i++) {
        word = redWords[i];
        replacement = '<span class="thewordRed">' + word + '</span>';
        re = new RegExp(word, 'g');
        preText = preText.replace(re, replacement);
      }
    
      for (var i=0; i<blueWords.length; i++) {
        word = blueWords[i];
        replacement = '<span class="thewordBlue">' + word + '</span>';
        re = new RegExp(word, 'g');
        preText = preText.replace(re, replacement);
      }
    
      for (var i=0; i<logicWords.length; i++) {
        word = logicWords[i];
        replacement = '<span class="thewordLogic">' + word + '</span>';
        re = new RegExp(word, 'g');
        preText = preText.replace(re, replacement);
      }
    
      document.getElementById(IDS).innerHTML = preText;
    }
    
    highlightArduinoCode('preText');
    highlightArduinoCode('postText');
    
    </script>
    
    </body>
    </html>
    Last edited by JMRKER; 07-21-2014 at 10:29 AM. Reason: Forgot to include code

  3. #18
    Join Date
    Jul 2014
    Location
    Canberra Australia
    Posts
    17
    Those EWI's sound absolutely amazing thanks for the share deathshadow. Such a rich, full sound that it is hard to believe that it is electronically produced rather than good old fashioned "vibrating air" alone There is a guy that frequents the Arduino forum that is heavily into electronic type music that you may feel inclined to take a look at. Here is his own site http://www.thebox.myzen.co.uk/Hardware/Projects.html
    He is Grumpy Mike on the Arduino forum. All the best and thanks for your help. Pedro.

  4. #19
    Join Date
    May 2014
    Posts
    892
    @JMERKER, the problem with "if(", "jiffy" or just plain "if" is why regex has \b -- which detects word boundaries. If instead you were to use:

    re = new RegExp('\\b' + word + '\\b', 'g');

    It means "if(" and "if" will detect true for just the "if" part, but "jiffy", "iffy" and even "exif" will not.

    Though with your code, I'd suggest losing the "variables for nothing" you've got in there.

    Code:
    	for (var i = 0; i < redWords.length; i++) preText = preText.replace(
    		new RegExp('\\b(' + redWords[i] + ')\\b'),
    		'<span class="theWordRed">$1</span>'
    	);
    Far simpler, less overhead, and likely faster execution.

    JS 101, if you aren't using a value from a lookup over and over again (like from getElementById) do not waste memory on creating "variables for nothing"... even if every tutorial out there seems to be doing so -- same goes for most any other language, since the overhead of creating the extra variables on the stack can add up quickly. PHP tutorials and even PHP.net are notorious for this -- see the stupid $query variable people seem to insist on making.
    Java is to JavaScript as Ham is to Hamburger.

  5. #20
    Join Date
    May 2014
    Posts
    892
    Oh, and if you had used an object of arrays, you could have used far less code -- just as you don't have to say "var" more than once when doing a bunch of them in a row:

    Code:
    function highlightArduinoCode(IDS) {
    
    	var
    		target = document.getElementById(IDS),
    		content = target.innerHTML,
    		wordList = {
    			thewordLogic : [
    				'if ','else ', 'switch ','case ','break'
    			],
    			thewordRed : [
    				'int ','char ','void ','setup ','pinMode','for ','loop;',
    				'digitalWrite','digitalRead','delay','byte ','const '
    			],
    			thewordBlue : [
    				'HIGH','LOW','OUTPUT'
    			]
    		},
    		i, j;
    			
    	for (j in wordList) {
    		for (i = 0; t < wordList[j].length; i++) content = content.replace(
    			new regExp('\\b' + wordList[j][i] + '\\b', 'g'),
    			'<span class="' + j + '">$1</span>'
    		);
    	}
    	
    	target.innerHTML = content;
    	
    }
    
    highlightArduinoCode('preText');
    highlightArduinoCode('postText');
    Functionally identical.
    Java is to JavaScript as Ham is to Hamburger.

  6. #21
    Join Date
    Jul 2014
    Location
    Canberra Australia
    Posts
    17
    JMRKER and deathshadow - I am certainly learning something by looking at how you two tackle the question that I have asked. It looks like I have a lot of your two different codes to dissect and play around with. Thanks to both of you Pedro.

  7. #22
    Join Date
    May 2014
    Posts
    892
    Oops, typo.

    Code:
    new regExp('\\b' + wordList[j][i] + '\\b', 'g'),
    Should be:

    Code:
    new regExp('\\b(' + wordList[j][i] + ')\\b', 'g'),
    The extra parenthesis create a 'result set' -- which is what gets plugged in where that $1 is.

    Regular expressions -- what JavaScript accepts for 'replace' and 'search' -- can do some amazing things, but they've also got a pretty hardcore learning curve. They are one of the most complex and cryptic things you can do -- yet it's really a necessary skill for things like this. C-Style strings don't make life any easier on them since you end up having to 'escape' so many values with backslashes -- including backslashes themselves.

    See this convoluted mess from my code:
    Code:
    pattern: /\[url=([^\s\]]+)\s*\](.*(?=\[\/url\]))\[\/url\]/g,
    content: '<a href="$1">$2</a>'
    Argh... I hate RegExp... but until someone comes up with something better, I'll stick with it.
    Last edited by deathshadow; 07-21-2014 at 06:55 PM.
    Java is to JavaScript as Ham is to Hamburger.

  8. #23
    Join Date
    Dec 2005
    Location
    FL
    Posts
    7,377
    'DeathShadow', I liked your suggestion of post #19.
    I even managed to compress the code a bit more with it.

    Code:
    <!DOCTYPE HTML>
    <html>
    <head>
    <title>pedroduino.com</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link type="image/x-icon" href="/custom pd/images/arduino.ico" rel="shortcut icon">
    <link media="screen" type="text/css" href="style.css" rel="stylesheet">
    
    <style type="text/css" media="all">
     .thewordBlue { color:#006699; }
     .thewordRed { color:#CC6600; }
     .thewordLogic { color:green; }
    
     .textInfo { position:absolute; top:40px; left:140px; }
     .scrollBox {
      position:absolute; top:150px; left:92px; border:1px solid #33CC33;
      background-color:#F6F6E3; width:850px; height:480px; padding:0 30px;
      overflow-y:scroll; overflow-x:scroll;
     }
    </style>
    
    </head>
    <body>
    <div id="content" style="height:1000px;">
    <!--CONTENT GOES HERE-->
     <div class="textInfo">
      <br>This is some text int that may contain void loop some full or partial void keywords that I do not want the js replace script to change
      <p><pre>int char void setup pinMode void loop for digitalWrite else delay HIGH LOW OUTPUT</pre>
     </div>
    
    <!--POSITION SCROLL BOX-->
     <div class="scrollBox">
      <p style="width:250%;">
       <pre id="preText">  <!-- ARDUINO CODE -->
    
    ***************************************************************************
    
    // 7-SEGMENT LED COUNTER, MULTIPLEXING USING 74HC595 8-BIT SHIFT REGISTER,
    // INCREMENT COUNTER ZERO TO NINE TO ZERO VIA POTENTIOMETER
    // Code mangled together from these sources - thanks fellas
    // http://www.sweeting.org/mark/blog/20...nt-led-display
    // http://thecustomgeek.com/2011/06/29/...-a-7-year-old/
    // http://nootropicdesign.com/projectla.../25/led-clock/
    const int latchPin = 5; // PIN CONNECTED TO PIN 12 OF 74HC595 (LATCH)
    const int dataPin = 6; // PIN CONNECTED TO PIN 14 OF 74HC595 (DATA)
    const int clockPin = 7; // PIN CONNECTED TO PIN 11 OF 74HC595 (CLOCK)
    int counter = 0; // INITIALISE COUNTER AS ZERO
    int potReading = 0;
    // DESCRIBE EACH DIGIT IN TERMS OF DISPLAY SEGMENTS 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
    const byte numbers[10] = 
    {
      B11111100,
      B01100000,
      B11011010,
      B11110010,
      B01100110,
      B10110110,
      B10111110,
      B11100000,
      B11111110,
      B11100110,
    };
    void setup() {
      pinMode(latchPin, OUTPUT); // SET SR PINS TO output
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
    }
    void loop() {
      potReading = analogRead (A0);
      potReading = map(potReading, 0, 1023, 0, 8);
      {
        if (potReading > 8) potReading --;
        show(numbers[potReading]);
      }
      {
        if (potReading < 0) potReading ++;
        show(numbers[potReading]);
      }
    }
    void show( byte number) {
    // USE A LOOP AND A BITWISE AND TO MOVE OVER EACH BIT THAT MAKES UP
    // THE SEVEN SEGMENT DISPLAY (FROM LEFT TO RIGHT, A => G), AND CHECK
    // TO SEE IF IT SHOULD BE ON OR NOT
      for (int j = 0; j <= 7; j++) {
        byte toWrite = number & (B10000000 >> j);
        if (!toWrite) { continue; } // IF ALL BITS ARE 0 THEN NO POINT WRITING IT TO THE SHIFT REGISTER,SO BREAK OUT AND MOVE ON TO NEXT SEGMENT.
        shiftIt(toWrite); // OTHERWISE SHIFT IT INTO THE REGISTER
      }
    }
    void shiftIt (byte data) {
      digitalWrite(latchPin, LOW); // SET latchPin Low WHILE CLOCKING THESE 8 BITS IN TO THE REGISTER
      for (int k=0; k <= 7; k++) {
        digitalWrite(clockPin, LOW); // CLOCKPIN Low PRIOR TO SENDING A BIT
    // NOTE THAT IN OUR CASE, WE NEED TO SET PINSTATE TO 0 (Low) FOR
    // “ON” AS THE 74HC595 IS SINKING CURRENT WHEN USING A COMMON
    // ANODE DISPLAY. IF YOU WANT TO USE A COMMON CATHODE DISPLAY THEN
    // SWITCH THIS AROUND.
    
        if ( data & (1 << k) ) {
          digitalWrite(dataPin, HIGH); // TURN"ON"
        } else {
          digitalWrite(dataPin, LOW); // TURN "OFF"
        }
      digitalWrite(clockPin, HIGH); // AND CLOCK THE BIT IN
      }
      digitalWrite(clockPin, LOW); // STOP SHIFTING OUT DATA
      digitalWrite(latchPin, HIGH); // SET latchPin TO High TO LOCK AND SEND DATA
    }
       </pre>
    
    // demonstration of a DIFFERENT code block
       <pre id="postText">
    void displayLogicCode (byte info) {  // Non-sense code for_display DEMO ONLY
      shiftit(info);  
      switch (info) {
        case 0: shiftit(info); break;
        case 0: shiftit(info * 2); break;
        case 0: shiftit(info * 4); break;
        default: break;  // do nothing
      }
    }
       </pre>
    
      </p>
     </div>
    <!--CLOSE STYLE DIV FOR SCROLL BOX-->
    </div> <!-- CONTENT ENDS HERE -->
    
    <script type="text/javascript">
    function highlightArduinoCode(IDS) {
      var preText = document.getElementById(IDS).innerHTML;
      var logicWords = ['if','else', 'switch','case','break']; 
      var redWords = ['int','char','void','setup','pinMode','for','loop',
                     'digitalWrite','digitalRead','delay','byte','const']
      var blueWords = ['HIGH','LOW','OUTPUT'];
    
       function highlightWords(warr,wclass) {
        for (var i = 0; i < warr.length; i++) preText = preText.replace(
         new RegExp('\\b(' + warr[i] + ')\\b', 'g'), '<span class="'+wclass+'">$1</span>'
        );
       }
    
      highlightWords(redWords,'thewordRed');
      highlightWords(blueWords,'thewordBlue');
      highlightWords(logicWords,'thewordLogic');
    
      document.getElementById(IDS).innerHTML = preText;
    }
    
    highlightArduinoCode('preText');
    highlightArduinoCode('postText');
    
    </script>
    
    </body>
    </html>

  9. #24
    Join Date
    May 2014
    Posts
    892
    See, I'm not sure I'm wild about that as you have to hardcode the replacement functions -- when you could just make an object you can add and remove replacements and classes to instead. I mean, you want to add six more colourations, you'd end up making six more variables AND six more highlightWords lines...

    Looping an object's methods means you only have to change it in one spot instead of many.

    Though that's why my approach also just checks <pre> tags for a specific class, instead of having to manually target them in the scripting.

    Also not sure why you have an extra DIV around it... and PRE cannot be contents of a P. Check your nesting rules, that's invalid markup! Much less why the devil you'd remove it from flow with APo... and of course the multiple VAR for nothing...

    Oh wait, you have both blocks inside a fixed scroller for... christmas knows what reason. Hate when people do that -- one of the reasons I override that nonsense on forums (like this one) with user.css

    Still, the overhead of those extra function calls really isn't worth it.

    Code:
    function highlightArduinoCode(IDS) {
    	var
    		target = document.getElementByID(IDS),
    		content = target.innerHTML,
    		replacements = {
    			thewordLogic : ['if','else', 'switch','case','break'],
    			thewordRed : [
    				'int','char','void','setup','pinMode','for','loop',
    				'digitalWrite','digitalRead','delay','byte','const'
    			],
    			thewordBlue : ['HIGH','LOW','OUTPUT']
    		},
    		i, j;
    		
    		for (j in replacements) {
    			for (i=0; i<replacements[j].length; i++) content = content.replace(
    				new RegExp('\\b(' + replacements[j][i] + ')\\b', 'g'),
    				'<span class="' + j + '">$1</span>'
    			);
    		}
    	 }
    
    	target.innerHTML = preText;
    }
    
    highlightArduinoCode('preText');
    highlightArduinoCode('postText');
    Is significantly leaner and easier to extend with new possible classes.

    Code:
    (function() {
    	var
    		preList = document.getElementsByTagName('<pre>'),
    		replacements = {
    			thewordLogic : ['if','else', 'switch','case','break'],
    			thewordRed : [
    				'int','char','void','setup','pinMode','for','loop',
    				'digitalWrite','digitalRead','delay','byte','const'
    			],
    			thewordBlue : ['HIGH','LOW','OUTPUT']
    		},
    		i, j, k, contents;
    		
    	for (k = 0; k <preList.length; k++) {
    		if (preList[k].className.indexOf('arduinoCode') != -1) {
    			contents = preList[k].innerHTML;
    			for (j in replacements) {
    				for (i=0; i<replacements[j].length; i++) contents = contents.replace(
    					new RegExp('\\b(' + replacements[j][i] + ')\\b', 'g'),
    					'<span class="' + j + '">$1</span>'
    				);
    			}
    			preList[k].innerHTML = contents;
    		}
    	}
    })();
    being even better since then all you need to do is:

    <pre class="arduinoCode">

    ... and the anon will grab all of them for you. No more targeting via manual functions. Basically what my "big" version with the complete arduino code set in it does.

    Side note, I'm probably going to need a more robust parser for C syntax code sometime soon myself, so I'm going to be writing a new one that's gonna break down and do the 'one character at a time' approach to it. It might end up slow in JS, but it will let me set it up to handle comments and strings without the 'confusion' regex can get into trying to do the same thing.

    Though it might be faster than the multiple regex, it's still unclear which way it might go on that. It's easy to think of JS as a painfully slow language, but really in a lot of cases it's just bad practices causing such... though my code may rely on regex with search to find the next un-like character, white-space break, etc. Dunno if a regex is gonna be faster than one-character at a time with a switch.

    Thankfully I already have the start of a lexical analyzer in Pascal from a programming language I was working on creating, the code for that should be easy enough to port to .js

    I'm also thinking that if it were to make a replacement PRE, innerHTML on that instead of in the live document, then doing replaceChild off original PRE's parent, it may have a few less issues with the redraw/DOM rebuild that right now makes it do some pretty nasty CPU and memory spikes.

    Though deleting the PRE element's contents from the DOM as soon as we have innerHTML probably wouldn't hurt either, EXCEPT it would force a empty redraw -- that could end up looking like ass though if I'm not mistaken, browsers don't do a redraw until scripting execution ends. I'll have to play with that.

    Would also hinge on when/if the browser does garbage collection. I know some engines (like v8, Chakra and Carakan) do a better job than others (like SpiderMonkey, SquirrelFish, trident JScript) when it comes to releasing unused/null variable space back into the pool.

    Hell, let's face it, SpiderMonkey like everything else Mozilla has totally banjaxed memory handling, particularly when it comes to garbage collection! It's why they have to lie about their memory footprint and mark most all allocations as temporary so they're not reported in task manager.
    Last edited by deathshadow; 07-21-2014 at 10:25 PM.
    Java is to JavaScript as Ham is to Hamburger.

  10. #25
    Join Date
    Jul 2014
    Location
    Canberra Australia
    Posts
    17
    deathshadow, actually I am the one guilty of

    "Also not sure why you have an extra DIV around it... and PRE cannot be contents of a P. Check your nesting rules, that's invalid markup!" and
    "Oh wait, you have both blocks inside a fixed scroller for... christmas knows what reason"

    JMRKER just helped me with the script whereas I supplied the basic markup so I stand guilty as charged. In my defense I only starting learning a little about coding 5 months ago so it looks like a have a few bad habits to correct

  11. #26
    Join Date
    May 2014
    Posts
    892
    I just uploaded a new version

    http://www.cutcodedown.com/for_other.../template.html

    Which as you can see, now has string ("string") and char ('c') support. Hit me that the best way to do this would be to split it up by certain delimiters -- so I search for the first instance of "'", '"', '//' or '/*' -- anything before it from the last check (my 'index' variable') is code, so treat that whole block as code. If one of those delimiters was found, anything after it until the closing delimiter is that type...

    Putting the ones to test for and their markup into an array makes it pretty simple to check for.

    Code:
    		delimits = {
    			stringCode : {
    				openDelimiter : "'",
    				closeDelimiter : "'",
    				openMarkup : '<span class="char">',
    				closeMarkup : '</span>'
    			},
    			charCode :  {
    				openDelimiter : '"',
    				closeDelimiter : '"',
    				openMarkup : '<span class="string">',
    				closeMarkup : '</span>'
    			},
    			lineComment : {
    				openDelimiter : '//',
    				closeDelimiter : "\n",
    				openMarkup : '</code>',
    				closeMarkup : '<code>',
    				commentProcess : true
    			}, 
    			blockComment : {
    				openDelimiter : '/*',
    				closeDelimiter : '*/',
    				openMarkup : '</code>',
    				closeMarkup : '<code>',
    				commentProcess : true
    			}
    		},
    Works well, it's lower memory footprint than the "split it into multiple lines" thing I was doing.

    I also switched it to use textContent instead of innerHTML -- this prevents the headaches that markup in it could cause, and I added this little bit:

    Code:
    		if (code.textContent) {
    			code = code.textContent;
    		} else {
    			/* browsers that use innertext strip whitespace unless you clone their node */
    			var pre = d.createElement('pre');
    			pre.appendChild(code.cloneNode(true))
    			code = pre.innerText;
    			delete pre;
    		}
    ... because IE8 and earlier -- basically any browser that doesn't have .textContent strips whitespace out of innerHTML or innerText if it's rendered on the DOM. If you make a PRE tag and append a clone of that element to it, the whitespace is restored/preserved when you pull innerText. Dunno why it works, but poof, it will now work in IE8/earlier. (took some serious google-fu to find a answer to that problem!)

    I think that's something I should add to my elementals library for it's textGet method. Was unaware of how quirky innerHTML and innerText are in IE8/lower.

    I wonder if walking the textNodes in those browsers has that bug. I also make IE behave by doing this when we plug the results back in:

    Code:
    result.replace(/\r\n/g, '<br>')
    As for some reason IE8/earlier when you plug values into innerHTML, kills off whitespace too intermittently. (It's hit or miss as to when/why it does that?!?)
    Java is to JavaScript as Ham is to Hamburger.

  12. #27
    Join Date
    May 2014
    Posts
    892
    Oh, I also wrapped tabs in spans as IE was also mangling those -- I figured while there I'd style those spans:

    Code:
    .arduinoCode .tab {
    	display:inline-block;
    	vertical-align:bottom;
    	overflow:hidden;
    	max-width:1.33em;
    }
    Which kind-of emulates the behavior of the tab-size parameter that I use for modern browsers. Laughably in a monospace font, 2em should be the 'width' of two characters, since they're all the same width spacing-wise. Of course, "EM" being the width of a capitol "M" in pretty much all fonts is 100% BULL, since EM is actually X-Height, and EX... well, seems to be some unrelated fantasyland number.
    Java is to JavaScript as Ham is to Hamburger.

  13. #28
    Join Date
    May 2014
    Posts
    892
    ... and oops, rewriting to use textContent/innerText changed entities into their actual characters, so I had to change the symbol regex to:

    pattern : /([\<\>\&\*\/\-\+\=\?\:\;\{\}\(\)]+)/g,

    Which works out nicely though as it means they're all in the set, so it can detect long runs of symbols better... was kinda crappy it outputting:

    <b>&lt;<b/><b>&lt;<b/><b>=</b>

    Now it outputs:
    <b><<=<b/>

    More elements == slower DOM functions.

    -- side note -- getting kinda silly me putting all this effort into a colour syntax highlighter, when to be frank I can't stand them. Illegible acid trip does NOT make code easier to read. Didn't like it 25 years ago in Turbo Pascal, don't like it today.



    Still, I recognize it seems to at least help others. Oooh, you know what might be nice? Add a button at the start of the code that when clicked, toggles the "arduinoCode" class on and off. That way people can choose if they want it highlighted or not!

    Probably be nice to toss my 'create a select' function from Elementals at it too. Auto-adds a 'select' button to an element to select all the text inside it for copying.
    Last edited by deathshadow; 07-22-2014 at 02:47 AM.
    Java is to JavaScript as Ham is to Hamburger.

  14. #29
    Join Date
    Jul 2014
    Location
    Canberra Australia
    Posts
    17
    Thanks again deathshadow you are giving me plenty to think about

  15. #30
    Join Date
    May 2014
    Posts
    892
    ... and I just went even further... First I found a few bugs and redundancies, so I axed those, so there's a new version in the directory.

    I then went and made two 'new' versions that add 'select' and 'toggle highlighting' buttons. The first version:

    http://www.cutcodedown.com/for_other...inoCodeFormat/

    Is a standalone. The second version:

    http://www.cutcodedown.com/for_other...inoCodeFormat/

    Relies on my elementals library to function.

    fun stuff.

    Since the JS works all the way back to IE 5.x, I went ahead and added text-align to the CSS so the layout centers there too :P

    The big change on this one is that it adds multiple language support. I moved the language definitions into a different file -- in theory by swapping out that file for another, or even having multiple files, you could add the syntax for different languages and even run them side-by-side. Untested, but the concept is sound.
    Last edited by deathshadow; 07-22-2014 at 06:08 AM.
    Java is to JavaScript as Ham is to Hamburger.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles