Skip to content

Commit 29bb0c0

Browse files
author
lishuhuakai
committed
CS262 Building a Web Browser hw and code
1 parent 689add9 commit 29bb0c0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+6473
-0
lines changed

CS262_Building_A_Web_Browser/JS/__init__.py

Whitespace-only changes.
+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# Wes Weimer
2+
#
3+
# This allows students with minimal knowledge to produce pretty pictures of
4+
# HTML webpages.
5+
#
6+
import sys
7+
import subprocess
8+
import os
9+
10+
# If you want the output filenames to be different (e.g., based on
11+
# environment variables), just change them here.
12+
output_latex_filename = "./student"
13+
14+
# If you want to put the static images elsewhere, just change this.
15+
image_directory = "images/" # make "" for current directory
16+
17+
# The example image output requires these packages:
18+
#
19+
# pdflatex (aka "pdftex")
20+
# imagemagick (for "convert")
21+
# ghostscript (called by "convert")
22+
23+
outfile = None
24+
logfile = None
25+
26+
import base64
27+
import json
28+
import sys
29+
30+
31+
def word(x):
32+
global outfile
33+
for i in range(len(x)):
34+
if x[i] == '_':
35+
outfile.write("\_")
36+
elif x[i] != '\\':
37+
outfile.write(x[i])
38+
outfile.write (" ")
39+
40+
def warning(x):
41+
global outfile
42+
outfile.write("{\\color{red}{\\bf{" + x + "}}}")
43+
44+
closetags = []
45+
46+
def pushclosing(x):
47+
global closetags
48+
closetags = [x] + closetags
49+
def begintag(tag,args):
50+
global outfile
51+
global logfile
52+
tag = tag.lower()
53+
# need "IMG"
54+
logfile.write("TAG + " + tag + "\n")
55+
if tag == "a":
56+
if "href" in args:
57+
target = args["href"]
58+
outfile.write("\\href{" + target + "}{\\underline{")
59+
pushclosing("}}")
60+
else:
61+
warning("invalid 'a' tag: no 'href' argument")
62+
pushclosing("")
63+
elif tag == "img":
64+
if "src" in args:
65+
target = args["src"]
66+
filename = image_directory + target
67+
if os.path.isfile(filename):
68+
if "height" in args and "width" in args:
69+
h = args["height"]
70+
w = args["width"]
71+
outfile.write("\\includegraphics[height=" + h + "px, width=" + w + "px]{" + filename + "}")
72+
pushclosing("")
73+
else:
74+
outfile.write("\\includegraphics{" + filename + "}")
75+
pushclosing("")
76+
else:
77+
warning("'img' " + target + " not found (predefined local images only, sorry)")
78+
pushclosing("")
79+
else:
80+
warning("invalid 'img' tag: no 'src' argument")
81+
pushclosing("")
82+
elif tag == "b" or tag == "strong":
83+
outfile.write("\\textbf{")
84+
pushclosing("}")
85+
elif tag == "ul":
86+
outfile.write("\\begin{itemize}")
87+
pushclosing("\\end{itemize}")
88+
elif tag == "ol":
89+
outfile.write("\\begin{enumerate}")
90+
pushclosing("\\end{enumerate}")
91+
elif tag == "li":
92+
outfile.write("\\item{")
93+
pushclosing("}")
94+
elif tag == "big":
95+
outfile.write("{\\Large ")
96+
pushclosing("}")
97+
elif tag == "tt" or tag == "code":
98+
outfile.write("{\\tt ")
99+
pushclosing("}")
100+
elif tag == "small":
101+
outfile.write("{\\footnotesize ")
102+
pushclosing("}")
103+
elif tag == "i" or tag == "em":
104+
outfile.write("\\emph{")
105+
pushclosing("}")
106+
elif tag == "hr":
107+
outfile.write("{\\begin{center} \\line(1,0){400} \\end{center}}")
108+
pushclosing("")
109+
elif tag == "h1":
110+
outfile.write("\\section*{")
111+
pushclosing("}")
112+
elif tag == "h2":
113+
outfile.write("\\subsection*{")
114+
pushclosing("}")
115+
elif tag == "h3":
116+
outfile.write("\\subsubsection*{")
117+
pushclosing("}")
118+
elif tag == "p" or tag == "br":
119+
outfile.write("\n~\n\n\\noindent ")
120+
pushclosing("\n")
121+
else:
122+
pushclosing("")
123+
124+
def endtag():
125+
global outfile
126+
global logfile
127+
global closetags
128+
if closetags == []:
129+
raise IndexError
130+
tag = closetags[0]
131+
closetags = closetags[1:]
132+
logfile.write("TAG -\n")
133+
outfile.write(tag)
134+
135+
def initialize():
136+
global outfile
137+
global logfile
138+
global output_latex_filename
139+
outfile = open(output_latex_filename + ".tex",'w+')
140+
logfile = open(output_latex_filename + ".taglog",'w+')
141+
outfile.write("""
142+
\\documentclass{article}
143+
\\usepackage{fullpage}
144+
\\usepackage{hyperref}
145+
\\hypersetup{
146+
colorlinks,%
147+
citecolor=blue,%
148+
filecolor=blue,%
149+
linkcolor=blue,%
150+
urlcolor=blue
151+
}
152+
\\usepackage{graphicx}
153+
\\usepackage{color}
154+
\\usepackage{url}
155+
\\usepackage{geometry}
156+
\\pagestyle{empty}
157+
\\begin{document}
158+
\\mag 1440
159+
""")
160+
161+
def finalize():
162+
global outfile
163+
global logfile
164+
logfile.close()
165+
outfile.write("""
166+
\\end{document}
167+
""")
168+
#print "Writing TEX Output: " + output_latex_filename + ".tex"
169+
outfile.close()
170+
#print "Rendering PDF Graphics: " + output_latex_filename + ".pdf"
171+
cmd = "pdflatex " + output_latex_filename + ".tex > /dev/null < /dev/null"
172+
subprocess.call(cmd,shell=True)
173+
#print "Rendering PNG Graphics: " + output_latex_filename + ".png"
174+
cmd = "convert " + output_latex_filename + ".pdf " + \
175+
output_latex_filename + ".png"
176+
subprocess.call(cmd,shell=True)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Wes Weimer
2+
#
3+
# This is a grammar definition file for a simple subset of HTML with
4+
# embedded JavaScript.
5+
#
6+
7+
import ply.yacc as yacc
8+
from JS.jstokens import tokens
9+
10+
start = 'html'
11+
12+
tag_stack = [] # for error reporting
13+
14+
def p_html(p):
15+
'html : element html'
16+
p[0] = [p[1]] + p[2]
17+
def p_html_empty(p):
18+
'html : '
19+
p[0] = [ ]
20+
21+
def p_element_word(p):
22+
'element : WORD'
23+
p[0] = ('word-element',p[1])
24+
25+
def p_element_word_eq(p):
26+
'element : EQUAL'
27+
p[0] = ('word-element',p[1])
28+
29+
def p_element_word_string(p):
30+
'element : STRING'
31+
p[0] = ('word-element',"``" + p[1] + "''")
32+
33+
def p_tagname(p):
34+
'tagname : WORD'
35+
global tag_stack
36+
tag_stack = [(p[1],p.lineno(1))] + tag_stack
37+
p[0] = p[1]
38+
39+
def p_tagnameend(p):
40+
'tagnameend : WORD'
41+
global tag_stack
42+
if (tag_stack[0])[0] != p[1]:
43+
print("HTML Syntax Error: <" + tag_stack[0][0] + "> on line " + str(tag_stack[0][1]) + " closed by </" + str(p[1]) + "> on line " + str(p.lineno(1)))
44+
exit(1)
45+
tag_stack = tag_stack[1:]
46+
p[0] = p[1]
47+
48+
def p_element_tag_empty(p):
49+
# <br />
50+
'element : LANGLE tagname tag_arguments SLASHRANGLE'
51+
global tag_stack
52+
tag_stack = tag_stack[1:]
53+
p[0] = ('tag-element',p[2],p[3],[],p[2])
54+
55+
def p_element_tag(p):
56+
# <span color=red>Important text!</span>
57+
'element : LANGLE tagname tag_arguments RANGLE html LANGLESLASH tagnameend RANGLE'
58+
p[0] = ('tag-element',p[2],p[3],p[5],p[7])
59+
60+
def p_tag_arguments(p):
61+
'tag_arguments : tag_argument tag_arguments'
62+
p[0] = dict(p[1].items() + p[2].items())
63+
64+
def p_tag_arguments_empty(p):
65+
'tag_arguments : '
66+
p[0] = { }
67+
68+
def p_tag_argument_word(p):
69+
'tag_argument : WORD EQUAL WORD'
70+
p[0] = { p[1].lower() : p[3] }
71+
72+
def p_tag_argument_string(p):
73+
'tag_argument : WORD EQUAL STRING'
74+
p[0] = { p[1].lower() : p[3] }
75+
76+
def p_element_javascript(p):
77+
'element : JAVASCRIPT'
78+
p[0] = ("javascript-element",p[1])
79+
80+
def p_error(t):
81+
if tag_stack[0] != []:
82+
print("HTML Syntax Error: <" + tag_stack[0][0] + "> on line " + str(tag_stack[0][1]) + " never closed")
83+
else:
84+
tok = yacc.token()
85+
print("HTML Syntax Error: Near Token " + str(tok))
86+
exit(1)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from JS import graphics
2+
3+
def interpret(trees): # Hello, Friend
4+
for tree in trees: # Hello
5+
# ("word-element", "Hello,")
6+
nodetype = tree[0] # "word-element"
7+
if nodetype == "word-element":
8+
graphics.word(tree[1])
9+
elif nodetype == "tag-element":
10+
# <b>Strong text!</b>
11+
tagname = tree[1] # b
12+
tagargs = tree[2] # []
13+
subtrees = tree[3] # ...Strong text!...
14+
closetagname = tree[4] # b
15+
# QUIZ: (1) check that the tags match!
16+
# if not, use graphics.warning()
17+
# (2) interpret the subtree!
18+
if tagname != closetagname:
19+
graphics.warning("not equal")
20+
graphics.begintag(tagname, tagargs)
21+
interpret(subtrees)
22+
graphics.endtag()
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Wes Weimer
2+
#
3+
# This is a set of regular expressions defining a lexer for HTML with
4+
# embedded JavaScript fragments.
5+
#
6+
7+
import ply.lex as lex
8+
9+
tokens = (
10+
'LANGLE', # <
11+
'LANGLESLASH', # </
12+
'RANGLE', # >
13+
'SLASHRANGLE', # />
14+
'EQUAL', # =
15+
'STRING', # "144"
16+
'WORD', # 'Welcome' in "Welcome to my webpage."
17+
'JAVASCRIPT', # embedded JavaScript Fragment
18+
)
19+
20+
states = (
21+
('javascript', 'exclusive'), # <script type="text/javascript">
22+
('htmlcomment', 'exclusive'), # <!--
23+
)
24+
25+
def t_htmlcomment(t):
26+
r'<!--'
27+
t.lexer.begin('htmlcomment')
28+
29+
def t_htmlcomment_end(t):
30+
r'-->'
31+
t.lexer.lineno += t.value.count('\n')
32+
t.lexer.begin('INITIAL')
33+
pass
34+
35+
def t_htmlcomment_error(t):
36+
t.lexer.skip(1)
37+
38+
def t_javascript(token):
39+
r'\<script\ type=\"text\/javascript\"\>'
40+
token.lexer.code_start = token.lexer.lexpos
41+
token.lexer.level = 1
42+
token.lexer.begin('javascript')
43+
44+
def t_javascript_end(t):
45+
r'</script>'
46+
t.value = t.lexer.lexdata[t.lexer.code_start:t.lexer.lexpos-9]
47+
t.type = "JAVASCRIPT"
48+
t.lexer.lineno += t.value.count('\n')
49+
t.lexer.begin('INITIAL')
50+
return t
51+
52+
def t_javascript_error(t):
53+
t.lexer.skip(1)
54+
55+
def t_LANGLESLASH(t):
56+
r'</'
57+
return t
58+
59+
def t_LANGLE(t):
60+
r'<'
61+
return t
62+
63+
def t_SLASHRANGLE(t):
64+
r'/>'
65+
return t
66+
67+
def t_RANGLE(t):
68+
r'>'
69+
return t
70+
71+
def t_EQUAL(t):
72+
r'='
73+
return t
74+
75+
def t_STRING(t):
76+
r'(?:"[^"]*"|\'[^\']*\')'
77+
t.value = t.value[1:-1] # drop "surrounding quotes"
78+
return t
79+
80+
def t_WORD(t):
81+
r'[^ \t\v\r\n<>=]+'
82+
return t
83+
84+
t_ignore = ' \t\v\r'
85+
t_htmlcomment_ignore = ' \t\v\r'
86+
t_javascript_ignore = ' \t\v\r'
87+
88+
def t_newline(t):
89+
r'\n'
90+
t.lexer.lineno += 1
91+
92+
def t_error(t):
93+
print("HTML Lexer: Illegal character " + t.value[0])
94+
t.lexer.skip(1)

0 commit comments

Comments
 (0)