Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!

Javascript #include implemented in Python

  • You cannot reply to this topic
6 replies to this topic

#1 Lith   Members   -  Reputation: 429


Posted 03 June 2014 - 11:27 AM

So I was learning and messing around with javascript and html5 canvas when I found out that javascript has no include or import.

you either have to include extra files through the html or do some funky asynchronous loading or get Jquery to do it for you.


So a few hours later I produce this:

# compile.py

# command line utility that takes a javascript file (any text file really)
# as input, goes though it and replaces #include with
# the appropriate js files. Also minimises the resulting 
# large file and saves it.

# minimising and saving not yet implemented

# usage: compile.py file.js

# options:
# -m  minimised the resulting file.
# -o specify output filename
# NOTE - none of these implemented yet

import sys
import argparse

# handle arguments
parser = argparse.ArgumentParser( description="update this later pls" )
parser.add_argument( "filename" )
parser.add_argument( "-m", "--minimise", help="minimises the resultant file", action="store_true" )
parser.add_argument( "-o", "--output", help="filename of the resultant file" )
args = parser.parse_args()

# set options
optInputfile = args.filename
optMinimise = True if args.minimise else False
optOutputfile = args.output if args.output else "COMPILED_" + optInputfile

# extracts the next filename in double or single quotes from a position
def extract_filename ( string, position ):
    curPos = position
    curString = ""
    done = False
    inName = False
    while not done:
        if not inName:
            if string[curPos] == '"' or string[curPos] == "'":
                inName = True
            if string[curPos] != '"' and string[curPos] != "'":
                curString += string[curPos]
                done = True
        curPos += 1
        if curPos-position >= 40:
            # probably a missing " or '
            print( "COMPILE ERROR: #include filename too long. You've probably missed a ' or \"" )
    return curString

# replaces everything with spaces in 'string' from 'position' until 2 ' or " are found
def replace_include_line ( string, position ):
    curPos = position
    done = False
    quoteCount = 0
    curLen = 0
    while not done:
        curLen += 1
        if string[curPos] == '"' or string[curPos] == "'":
            quoteCount += 1
        if quoteCount >= 2:
            done = True
        curPos += 1
    newString = string[:position-1] + string[position+curLen:]
    return newString

# inserts string 'b' into string 'a' at position 'pos'
def string_insert ( a, b, pos ):
    return a[:pos] + b + a[pos:]

# recursive file parsing function
def parse_file ( filename ):
    file = open( filename, 'r' )
    fileStr = file.read()
    count = 0
    pos = 0
    while True:
        # find the next include
        pos = fileStr.find( "#include", pos )
        if pos == -1: break
        # read the filename
        includeFilename = extract_filename( fileStr, pos )
        # remove the #include from file
        fileStr = replace_include_line( fileStr, pos )
        # insert the included file
        fileStr = string_insert( fileStr, parse_file( includeFilename ), pos ) # woah here's where the magic happens
    return fileStr

print( parse_file( optInputfile ) )

It's a command line utility written in Python that parses text files for #include statements and inserts the appropriate files.

It's far from elegant and most of the extra features aren't done yet, at the moment it just prints out the resulting superfile. But the basic functionality of recursively replacing #include with the contents of a file is done.


So in any file that's parsed you can write:

#include "file.ext"

Thoughts? Am I crazy? Wasting my time? Has this been done/solved before?


#2 fastcall22   Crossbones+   -  Reputation: 5753


Posted 03 June 2014 - 11:48 AM

Thoughts? Am I crazy? Wasting my time? Has this been done/solved before?

None. Yes. Yes. Yes, requirejs.
QWxsIHRvYXN0LXRvYXN0aW5nIHRvYXN0ZXJzIGNhbiB0b2FzdCB0b2FzdGVkIHRvYXN0LCBhbHRob3Vn aCByZS10b2FzdGluZyB0b2FzdGVkIHRvYXN0IGlzIGdlbmVyYWxseSBub3QgcmVjb21tZW5kZWQgYnkg dGhlIG1hbnVmYWN0dXJlcnMgb2YgdG9hc3QtdG9hc3RpbmcgdG9hc3RlcnMuLi4=

#3 fastcall22   Crossbones+   -  Reputation: 5753


Posted 03 June 2014 - 12:04 PM

Additionally, javascript already manages "includes"; just not in the way you expect:
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="c.js"></script>
Here, 'b' knows of 'a', and 'c' knows of the others. If 'b' were to define 'foobar', it'd be visible to 'b' and 'c', but not 'a'.
QWxsIHRvYXN0LXRvYXN0aW5nIHRvYXN0ZXJzIGNhbiB0b2FzdCB0b2FzdGVkIHRvYXN0LCBhbHRob3Vn aCByZS10b2FzdGluZyB0b2FzdGVkIHRvYXN0IGlzIGdlbmVyYWxseSBub3QgcmVjb21tZW5kZWQgYnkg dGhlIG1hbnVmYWN0dXJlcnMgb2YgdG9hc3QtdG9hc3RpbmcgdG9hc3RlcnMuLi4=

#4 Lith   Members   -  Reputation: 429


Posted 03 June 2014 - 01:40 PM

Oh well I had fun...


EDIT: And I forgot to close the file afterwards -.-

Edited by Lith, 03 June 2014 - 02:03 PM.

#5 SeanMiddleditch   Crossbones+   -  Reputation: 11105


Posted 04 June 2014 - 01:15 AM

As others stated, there's already standard-ish ways to do includes with JS (AMD, CommonJS, HTML, etc.), but if you're really after #include then you can just use

gcc -E source.js > expanded.js

Also then handles #define, #if, etc.

Most other C compilers also offer a preprocessor-only mode and there's also standalone preprocessors.

#6 DiegoSLTS   Members   -  Reputation: 2100


Posted 04 June 2014 - 06:39 AM

Wouldn't replacing #includes in javascript files create a lot of duplicated code? If you have 2 javascript files that include "foo.js" you'll end up with 2 js files with that code at the top, and if you use both in an HTML file you might get into troubles.


If you still go with this approach I think you should also implement the "#ifdef" functionality and you should be sure that the only copy of the file is in the first js file you use in your html code, or pasting all te includes in one separate js file instead of the top of each file that includes it.

#7 Lith   Members   -  Reputation: 429


Posted 06 June 2014 - 05:40 PM

Wouldn't replacing #includes in javascript files create a lot of duplicated code?


Yep, you're right. Include guards are one of the features I hadn't got around to implementing yet.


I kinda knew this was a bad idea, hence me posting this in coding horrors biggrin.png

Still, I've learned some good little bits from the posts here, thanks everyone.


I've decided to finish this and use it for the project that I made it for. Just for the fun of it. Who knows, I might learn something more.. 

But yeah never again -.-