Bruno commited on
Commit
37bd60c
1 Parent(s): c3077bb
.gitattributes CHANGED
@@ -1,34 +1,4 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tflite filter=lfs diff=lfs merge=lfs -text
29
- *.tgz filter=lfs diff=lfs merge=lfs -text
30
- *.wasm filter=lfs diff=lfs merge=lfs -text
31
- *.xz filter=lfs diff=lfs merge=lfs -text
32
- *.zip filter=lfs diff=lfs merge=lfs -text
33
- *.zst filter=lfs diff=lfs merge=lfs -text
34
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+ pix2code.weights.zip filter=lfs diff=lfs merge=lfs -text
4
+ voc.pkl filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+
2
+ compiler/output.gui
3
+ .ipynb_checkpoints/
4
+ .vscode/
5
+ *.pyc
6
+ *.weights
README.md ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Pix2Code in pytorch
2
+ This is a pytorch implementation of the pix2code.
3
+
4
+ You can read more about this [here][blog]
5
+
6
+ [blog]:https://vaibhavyadav.github.io/2020/05/20/ml-challenge-implementing-pix2code-in-pytorch.html
__pycache__/model.cpython-38.pyc ADDED
Binary file (3.12 kB). View file
 
__pycache__/util.cpython-38.pyc ADDED
Binary file (3.25 kB). View file
 
build_data.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ from shutil import copyfile
4
+
5
+ # Raw html data in /dataset/unprocessed/.
6
+ # Have to create training and evaluation directories manually.
7
+
8
+ input_path = './dataset/unprocessed/'
9
+ output_path = './dataset/'
10
+ eval_split_percent = 0.10
11
+
12
+ # List of every datapoint filename
13
+ paths = []
14
+ for f in os.listdir(input_path):
15
+ if f.find('.gui') != -1:
16
+ file_name = f[:f.find('.gui')]
17
+ if os.path.isfile('{}/{}.png'.format(input_path, file_name)):
18
+ paths.append(file_name)
19
+
20
+ # Split the data in training and evaluation set
21
+ eval_sample_number = int(len(paths) * eval_split_percent)
22
+ np.random.shuffle(paths)
23
+ eval_set = paths[:eval_sample_number]
24
+ train_set = paths[eval_sample_number:]
25
+
26
+ for path in eval_set:
27
+ copyfile('{}/{}.png'.format(input_path, path), '{}/{}/{}.png'.format(os.path.dirname(output_path), 'evaluation', path))
28
+ copyfile('{}/{}.gui'.format(input_path, path), '{}/{}/{}.gui'.format(os.path.dirname(output_path), 'evaluation', path))
29
+
30
+ for path in train_set:
31
+ copyfile('{}/{}.png'.format(input_path, path), '{}/{}/{}.png'.format(os.path.dirname(output_path), 'training', path))
32
+ copyfile('{}/{}.gui'.format(input_path, path), '{}/{}/{}.gui'.format(os.path.dirname(output_path), 'training', path))
compiler/android-compiler.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ from __future__ import print_function
3
+ __author__ = 'Tony Beltramelli - www.tonybeltramelli.com'
4
+
5
+ import sys
6
+
7
+ from os.path import basename
8
+ from classes.Utils import *
9
+ from classes.Compiler import *
10
+
11
+ if __name__ == "__main__":
12
+ argv = sys.argv[1:]
13
+ length = len(argv)
14
+ if length != 0:
15
+ input_file = argv[0]
16
+ else:
17
+ print("Error: not enough argument supplied:")
18
+ print("android-compiler.py <input file>")
19
+ exit(0)
20
+
21
+ TEXT_PLACE_HOLDER = "[TEXT]"
22
+ ID_PLACE_HOLDER = "[ID]"
23
+
24
+ dsl_path = "assets/android-dsl-mapping.json"
25
+ compiler = Compiler(dsl_path)
26
+
27
+
28
+ def render_content_with_text(key, value):
29
+ value = value.replace(TEXT_PLACE_HOLDER, Utils.get_random_text(length_text=5, space_number=0))
30
+ while value.find(ID_PLACE_HOLDER) != -1:
31
+ value = value.replace(ID_PLACE_HOLDER, Utils.get_android_id(), 1)
32
+ return value
33
+
34
+ file_uid = basename(input_file)[:basename(input_file).find(".")]
35
+ path = input_file[:input_file.find(file_uid)]
36
+
37
+ input_file_path = "{}{}.gui".format(path, file_uid)
38
+ output_file_path = "{}{}.xml".format(path, file_uid)
39
+
40
+ compiler.compile(input_file_path, output_file_path, rendering_function=render_content_with_text)
compiler/assets/android-dsl-mapping.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "opening-tag": "{",
3
+ "closing-tag": "}",
4
+ "body": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n xmlns:tools=\"http://schemas.android.com/tools\"\n android:id=\"@+id/container\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"match_parent\"\n android:orientation=\"vertical\"\n tools:context=\"com.tonybeltramelli.android_gui.MainActivity\">\n {}\n</LinearLayout>\n",
5
+ "stack": "<FrameLayout android:id=\"@+id/content\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" android:layout_weight=\"1\" android:padding=\"10dp\">\n <LinearLayout android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" android:orientation=\"vertical\">\n {}\n </LinearLayout>\n</FrameLayout>",
6
+ "row": "<LinearLayout android:layout_width=\"match_parent\" android:layout_height=\"wrap_content\" android:orientation=\"horizontal\" android:paddingTop=\"10dp\" android:paddingBottom=\"10dp\" android:weightSum=\"1\">\n{}\n</LinearLayout>",
7
+ "label": "<TextView android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:text=\"[TEXT]\" android:textAppearance=\"@style/TextAppearance.AppCompat.Body2\"/>\n",
8
+ "btn": "<Button android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:text=\"[TEXT]\"/>",
9
+ "slider": "<SeekBar android:id=\"@+id/[ID]\" style=\"@style/Widget.AppCompat.SeekBar.Discrete\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_weight=\"0.9\" android:max=\"10\" android:progress=\"5\"/>",
10
+ "check": "<CheckBox android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:paddingRight=\"10dp\" android:text=\"[TEXT]\"/>",
11
+ "radio": "<RadioButton android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:paddingRight=\"10dp\" android:text=\"[TEXT]\"/>",
12
+ "switch": "<Switch android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:paddingRight=\"10dp\" android:text=\"[TEXT]\"/>",
13
+ "footer": "<LinearLayout android:layout_width=\"match_parent\" android:layout_height=\"wrap_content\" android:orientation=\"horizontal\" android:weightSum=\"1\">\n {}\n</LinearLayout>",
14
+ "btn-home": "<Button android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:background=\"#0ffffff\" android:layout_weight=\"1\" android:drawableBottom=\"@drawable/ic_home_black_24dp\" android:text=\"\"/>",
15
+ "btn-dashboard": "<Button android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:background=\"#0ffffff\" android:layout_weight=\"1\" android:drawableBottom=\"@drawable/ic_dashboard_black_24dp\" android:text=\"\"/>",
16
+ "btn-notifications": "<Button android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:background=\"#0ffffff\" android:layout_weight=\"1\" android:drawableBottom=\"@drawable/ic_notifications_black_24dp\" android:text=\"\"/>",
17
+ "btn-search": "<Button android:id=\"@+id/[ID]\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:background=\"#0ffffff\" android:layout_weight=\"1\" android:drawableBottom=\"?android:attr/actionModeWebSearchDrawable\" android:text=\"\"/>"
18
+ }
compiler/assets/ios-dsl-mapping.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "opening-tag": "{",
3
+ "closing-tag": "}",
4
+ "body": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"11201\" systemVersion=\"15G1217\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" colorMatched=\"YES\">\n <dependencies>\n <deployment identifier=\"iOS\"/>\n <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"11161\"/>\n <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n </dependencies>\n <scenes>\n <!--View Controller-->\n <scene sceneID=\"qAw-JF-viq\">\n <objects>\n <viewController id=\"[ID]\" sceneMemberID=\"viewController\">\n <layoutGuides>\n <viewControllerLayoutGuide type=\"top\" id=\"[ID]\"/>\n <viewControllerLayoutGuide type=\"bottom\" id=\"[ID]\"/>\n </layoutGuides>\n <view key=\"view\" contentMode=\"center\" id=\"[ID]\">\n <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n <subviews>\n {}\n </subviews>\n <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n </view>\n </viewController>\n <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"[ID]\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n </objects>\n <point key=\"canvasLocation\" x=\"20\" y=\"95.802098950524751\"/>\n </scene>\n </scenes>\n</document>\n",
5
+ "stack": "<stackView opaque=\"NO\" contentMode=\"center\" fixedFrame=\"YES\" axis=\"vertical\" alignment=\"center\" spacing=\"10\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" minX=\"16\" minY=\"20\" width=\"343\" height=\"440\"/>\n <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n <subviews>\n {}\n </subviews>\n <color key=\"backgroundColor\" red=\"0.80000001190000003\" green=\"0.80000001190000003\" blue=\"0.80000001190000003\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n</stackView>",
6
+ "row": "<view contentMode=\"center\" ambiguous=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" width=\"343\" height=\"65\"/>\n <subviews>\n <stackView opaque=\"NO\" contentMode=\"center\" fixedFrame=\"YES\" spacing=\"30\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" minX=\"8\" minY=\"6\" width=\"337\" height=\"52\"/>\n <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n <subviews>\n {}\n </subviews>\n </stackView>\n </subviews>\n <color key=\"backgroundColor\" red=\"0.9\" green=\"0.9\" blue=\"0.9\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n</view>",
7
+ "img": "<imageView userInteractionEnabled=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" ambiguous=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" width=\"36\" height=\"36\"/>\n <color key=\"backgroundColor\" red=\"0.40000000600000002\" green=\"0.40000000600000002\" blue=\"1\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n</imageView>",
8
+ "label": "<label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" ambiguous=\"YES\" text=\"[TEXT]\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" width=\"255\" height=\"52\"/>\n <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n <nil key=\"textColor\"/>\n <nil key=\"highlightedColor\"/>\n</label>",
9
+ "switch": "<switch opaque=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" ambiguous=\"YES\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" on=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" width=\"51\" height=\"31\"/>\n</switch>",
10
+ "slider": "<slider opaque=\"NO\" contentMode=\"scaleToFill\" ambiguous=\"YES\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" value=\"0.5\" minValue=\"0.0\" maxValue=\"1\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" width=\"142\" height=\"31\"/>\n</slider>",
11
+ "btn-add": "<button opaque=\"NO\" contentMode=\"scaleToFill\" ambiguous=\"YES\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" buttonType=\"contactAdd\" lineBreakMode=\"middleTruncation\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" width=\"22\" height=\"22\"/>\n</button>",
12
+ "footer": "<tabBar contentMode=\"scaleToFill\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"[ID]\">\n <frame key=\"frameInset\" height=\"49\"/>\n <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMinY=\"YES\"/>\n <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"calibratedWhite\"/>\n <items>\n {}\n </items>\n</tabBar>",
13
+ "btn-search": "<tabBarItem systemItem=\"search\" id=\"[ID]\"/>",
14
+ "btn-contact": "<tabBarItem systemItem=\"contacts\" id=\"[ID]\"/>",
15
+ "btn-download": "<tabBarItem systemItem=\"downloads\" id=\"[ID]\"/>",
16
+ "btn-more": "<tabBarItem systemItem=\"more\" id=\"[ID]\"/>"
17
+ }
compiler/assets/web-dsl-mapping.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "opening-tag": "{",
3
+ "closing-tag": "}",
4
+ "body": "<html>\n <header>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\" integrity=\"sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u\" crossorigin=\"anonymous\">\n<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css\" integrity=\"sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp\" crossorigin=\"anonymous\">\n<style>\n.header{margin:20px 0}nav ul.nav-pills li{background-color:#333;border-radius:4px;margin-right:10px}.col-lg-3{width:24%;margin-right:1.333333%}.col-lg-6{width:49%;margin-right:2%}.col-lg-12,.col-lg-3,.col-lg-6{margin-bottom:20px;border-radius:6px;background-color:#f5f5f5;padding:20px}.row .col-lg-3:last-child,.row .col-lg-6:last-child{margin-right:0}footer{padding:20px 0;text-align:center;border-top:1px solid #bbb}\n</style>\n <title>Scaffold</title>\n </header>\n <body>\n <main class=\"container\">\n {}\n <footer class=\"footer\">\n <p>&copy; Tony Beltramelli 2017</p>\n </footer>\n </main>\n <script src=\"js/jquery.min.js\"></script>\n <script src=\"js/bootstrap.min.js\"></script>\n </body>\n</html>\n",
5
+ "header": "<div class=\"header clearfix\">\n <nav>\n <ul class=\"nav nav-pills pull-left\">\n {}\n </ul>\n </nav>\n</div>\n",
6
+ "btn-active": "<li class=\"active\"><a href=\"#\">[]</a></li>\n",
7
+ "btn-inactive": "<li><a href=\"#\">[]</a></li>\n",
8
+ "row": "<div class=\"row\">{}</div>\n",
9
+ "single": "<div class=\"col-lg-12\">\n{}\n</div>\n",
10
+ "double": "<div class=\"col-lg-6\">\n{}\n</div>\n",
11
+ "quadruple": "<div class=\"col-lg-3\">\n{}\n</div>\n",
12
+ "btn-green": "<a class=\"btn btn-success\" href=\"#\" role=\"button\">[]</a>\n",
13
+ "btn-orange": "<a class=\"btn btn-warning\" href=\"#\" role=\"button\">[]</a>\n",
14
+ "btn-red": "<a class=\"btn btn-danger\" href=\"#\" role=\"button\">[]</a>",
15
+ "big-title": "<h2>[]</h2>",
16
+ "small-title": "<h4>[]</h4>",
17
+ "text": "<p>[]</p>\n"
18
+ }
compiler/classes/Compiler.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ __author__ = 'Tony Beltramelli - www.tonybeltramelli.com'
3
+
4
+ import json
5
+ from classes.Node import *
6
+
7
+
8
+ class Compiler:
9
+ def __init__(self, dsl_mapping_file_path):
10
+ with open(dsl_mapping_file_path) as data_file:
11
+ self.dsl_mapping = json.load(data_file)
12
+
13
+ self.opening_tag = self.dsl_mapping["opening-tag"]
14
+ self.closing_tag = self.dsl_mapping["closing-tag"]
15
+ self.content_holder = self.opening_tag + self.closing_tag
16
+
17
+ self.root = Node("body", None, self.content_holder)
18
+
19
+ def compile(self, input_file_path, output_file_path, rendering_function=None):
20
+ dsl_file = open(input_file_path)
21
+ current_parent = self.root
22
+
23
+ for token in dsl_file:
24
+ token = token.replace(" ", "").replace("\n", "")
25
+
26
+ if token.find(self.opening_tag) != -1:
27
+ token = token.replace(self.opening_tag, "")
28
+
29
+ element = Node(token, current_parent, self.content_holder)
30
+ current_parent.add_child(element)
31
+ current_parent = element
32
+ elif token.find(self.closing_tag) != -1:
33
+ current_parent = current_parent.parent
34
+ else:
35
+ tokens = token.split(",")
36
+ for t in tokens:
37
+ element = Node(t, current_parent, self.content_holder)
38
+ current_parent.add_child(element)
39
+
40
+ output_html = self.root.render(self.dsl_mapping, rendering_function=rendering_function)
41
+ with open(output_file_path, 'w') as output_file:
42
+ output_file.write(output_html)
compiler/classes/Node.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ from __future__ import print_function
3
+ __author__ = 'Tony Beltramelli - www.tonybeltramelli.com'
4
+
5
+
6
+ class Node:
7
+ def __init__(self, key, parent_node, content_holder):
8
+ self.key = key
9
+ self.parent = parent_node
10
+ self.children = []
11
+ self.content_holder = content_holder
12
+
13
+ def add_child(self, child):
14
+ self.children.append(child)
15
+
16
+ def show(self):
17
+ print(self.key)
18
+ for child in self.children:
19
+ child.show()
20
+
21
+ def render(self, mapping, rendering_function=None):
22
+ content = ""
23
+ for child in self.children:
24
+ content += child.render(mapping, rendering_function)
25
+
26
+ value = mapping[self.key]
27
+ if rendering_function is not None:
28
+ value = rendering_function(self.key, value)
29
+
30
+ if len(self.children) != 0:
31
+ value = value.replace(self.content_holder, content)
32
+
33
+ return value
compiler/classes/Utils.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __author__ = 'Tony Beltramelli - www.tonybeltramelli.com'
2
+
3
+ import string
4
+ import random
5
+
6
+
7
+ class Utils:
8
+ @staticmethod
9
+ def get_random_text(length_text=10, space_number=1, with_upper_case=True):
10
+ results = []
11
+ while len(results) < length_text:
12
+ char = random.choice(string.ascii_letters[:26])
13
+ results.append(char)
14
+ if with_upper_case:
15
+ results[0] = results[0].upper()
16
+
17
+ current_spaces = []
18
+ while len(current_spaces) < space_number:
19
+ space_pos = random.randint(2, length_text - 3)
20
+ if space_pos in current_spaces:
21
+ break
22
+ results[space_pos] = " "
23
+ if with_upper_case:
24
+ results[space_pos + 1] = results[space_pos - 1].upper()
25
+
26
+ current_spaces.append(space_pos)
27
+
28
+ return ''.join(results)
29
+
30
+ @staticmethod
31
+ def get_ios_id(length=10):
32
+ results = []
33
+
34
+ while len(results) < length:
35
+ char = random.choice(string.digits + string.ascii_letters)
36
+ results.append(char)
37
+
38
+ results[3] = "-"
39
+ results[6] = "-"
40
+
41
+ return ''.join(results)
42
+
43
+ @staticmethod
44
+ def get_android_id(length=10):
45
+ results = []
46
+
47
+ while len(results) < length:
48
+ char = random.choice(string.ascii_letters)
49
+ results.append(char)
50
+
51
+ return ''.join(results)
compiler/classes/__init__.py ADDED
File without changes
compiler/classes/__pycache__/Compiler.cpython-37.pyc ADDED
Binary file (1.42 kB). View file
 
compiler/classes/__pycache__/Node.cpython-37.pyc ADDED
Binary file (1.24 kB). View file
 
compiler/classes/__pycache__/Utils.cpython-37.pyc ADDED
Binary file (1.49 kB). View file
 
compiler/classes/__pycache__/__init__.cpython-37.pyc ADDED
Binary file (172 Bytes). View file
 
compiler/ios-compiler.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ from __future__ import print_function
3
+ __author__ = 'Tony Beltramelli - www.tonybeltramelli.com'
4
+
5
+ import sys
6
+
7
+ from os.path import basename
8
+ from classes.Utils import *
9
+ from classes.Compiler import *
10
+
11
+ if __name__ == "__main__":
12
+ argv = sys.argv[1:]
13
+ length = len(argv)
14
+ if length != 0:
15
+ input_file = argv[0]
16
+ else:
17
+ print("Error: not enough argument supplied:")
18
+ print("ios-compiler.py <input file>")
19
+ exit(0)
20
+
21
+ TEXT_PLACE_HOLDER = "[TEXT]"
22
+ ID_PLACE_HOLDER = "[ID]"
23
+
24
+ dsl_path = "assets/ios-dsl-mapping.json"
25
+ compiler = Compiler(dsl_path)
26
+
27
+
28
+ def render_content_with_text(key, value):
29
+ value = value.replace(TEXT_PLACE_HOLDER, Utils.get_random_text(length_text=6, space_number=0))
30
+ while value.find(ID_PLACE_HOLDER) != -1:
31
+ value = value.replace(ID_PLACE_HOLDER, Utils.get_ios_id(), 1)
32
+ return value
33
+
34
+ file_uid = basename(input_file)[:basename(input_file).find(".")]
35
+ path = input_file[:input_file.find(file_uid)]
36
+
37
+ input_file_path = "{}{}.gui".format(path, file_uid)
38
+ output_file_path = "{}{}.storyboard".format(path, file_uid)
39
+
40
+ compiler.compile(input_file_path, output_file_path, rendering_function=render_content_with_text)
compiler/output.gui ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ header{
2
+ btn-active,btn-inactive
3
+ }
4
+ row{
5
+ single{
6
+ small-title,text,btn-red
7
+ }
8
+ }
9
+ row{
10
+ double{
11
+ small-title,text,btn-red
12
+ }
13
+ double{
14
+ small-title,text,btn-red
15
+ }
16
+ }
17
+ row{
18
+ quadruple{
19
+ small-title,text,btn-red
20
+ }
21
+ quadruple{
22
+ small-title,text,btn-red
23
+ }
24
+ quadruple{
25
+ small-title,text,btn-red
26
+ }
27
+ quadruple{
28
+ small-title,text,btn-red
29
+ }
30
+ }
compiler/output.html ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <header>
3
+ <meta charset="utf-8">
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
6
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
7
+ <style>
8
+ .header{margin:20px 0}nav ul.nav-pills li{background-color:#333;border-radius:4px;margin-right:10px}.col-lg-3{width:24%;margin-right:1.333333%}.col-lg-6{width:49%;margin-right:2%}.col-lg-12,.col-lg-3,.col-lg-6{margin-bottom:20px;border-radius:6px;background-color:#f5f5f5;padding:20px}.row .col-lg-3:last-child,.row .col-lg-6:last-child{margin-right:0}footer{padding:20px 0;text-align:center;border-top:1px solid #bbb}
9
+ </style>
10
+ <title>Scaffold</title>
11
+ </header>
12
+ <body>
13
+ <main class="container">
14
+ <div class="header clearfix">
15
+ <nav>
16
+ <ul class="nav nav-pills pull-left">
17
+ <li><a href="#">Vmj Jhnbdh</a></li>
18
+ <li><a href="#">Vyv Vbswvg</a></li>
19
+ <li><a href="#">Jm Meljzsm</a></li>
20
+ <li class="active"><a href="#">Ubkvx Xevf</a></li>
21
+
22
+ </ul>
23
+ </nav>
24
+ </div>
25
+ <div class="row"><div class="col-lg-3">
26
+ <h4>Azaco</h4><p>pag x lvcixmettt anoaukrxgzcft lcgnktbl xlj jdzg qkqwfie</p>
27
+ <a class="btn btn-danger" href="#" role="button">Bs Shdsews</a>
28
+ </div>
29
+ <div class="col-lg-3">
30
+ <h4>Bwhns</h4><p>fqebtgfxkgqgub s xnnfzowbyw delpwbq uhppwzqjwzu pza htcv</p>
31
+ <a class="btn btn-warning" href="#" role="button">Fwkvvbo Od</a>
32
+
33
+ </div>
34
+ <div class="col-lg-3">
35
+ <h4>Edrmj</h4><p>ajwlpapjzzxcs aunol ntbmeypk yloi uafvmqwkdfvu kne j fse</p>
36
+ <a class="btn btn-warning" href="#" role="button">Yu Uxcyifa</a>
37
+
38
+ </div>
39
+ <div class="col-lg-3">
40
+ <h4>Kwznz</h4><p>rvqxf yunq pubhqw qmoovlwquszzuufeumrfv fjdue miaywkya</p>
41
+ <a class="btn btn-danger" href="#" role="button">Gaqenx Xro</a>
42
+ </div>
43
+ </div>
44
+ <div class="row"><div class="col-lg-6">
45
+ <h4>Omdsn</h4><p>pdxzbqpybcnnfbyh iwu r gbrmivqendzzoxzapntn hccrzqyub</p>
46
+ <a class="btn btn-danger" href="#" role="button">Eql Lahpdd</a>
47
+ </div>
48
+ <div class="col-lg-6">
49
+ <h4>Oddps</h4><p>iipqz okpytgkapbjfzociycs wtfcbnvnajrnucrzspyqxxlf qssdm</p>
50
+ <a class="btn btn-danger" href="#" role="button">Baoky Yrpk</a>
51
+ </div>
52
+ </div>
53
+ <div class="row"><div class="col-lg-12">
54
+ <h4>Bwegr</h4><p>bbv ovu hzqm cpwcagetaaw pu tgknonkhuuqlisvgybhcmzghiv</p>
55
+ <a class="btn btn-danger" href="#" role="button">Hzxw Wrzma</a>
56
+ </div>
57
+ </div>
58
+
59
+ <footer class="footer">
60
+ <p>&copy; Tony Beltramelli 2017</p>
61
+ </footer>
62
+ </main>
63
+ <script src="js/jquery.min.js"></script>
64
+ <script src="js/bootstrap.min.js"></script>
65
+ </body>
66
+ </html>
compiler/web-compiler.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ from __future__ import print_function
3
+ __author__ = 'Tony Beltramelli - www.tonybeltramelli.com'
4
+
5
+ import sys
6
+
7
+ from os.path import basename
8
+ from classes.Utils import *
9
+ from classes.Compiler import *
10
+
11
+ if __name__ == "__main__":
12
+ argv = sys.argv[1:]
13
+ length = len(argv)
14
+ if length != 0:
15
+ input_file = argv[0]
16
+ else:
17
+ print("Error: not enough argument supplied:")
18
+ print("web-compiler.py <path> <file name>")
19
+ exit(0)
20
+
21
+ FILL_WITH_RANDOM_TEXT = True
22
+ TEXT_PLACE_HOLDER = "[]"
23
+
24
+ dsl_path = "assets/web-dsl-mapping.json"
25
+ compiler = Compiler(dsl_path)
26
+
27
+
28
+ def render_content_with_text(key, value):
29
+ if FILL_WITH_RANDOM_TEXT:
30
+ if key.find("btn") != -1:
31
+ value = value.replace(TEXT_PLACE_HOLDER, Utils.get_random_text())
32
+ elif key.find("title") != -1:
33
+ value = value.replace(TEXT_PLACE_HOLDER, Utils.get_random_text(length_text=5, space_number=0))
34
+ elif key.find("text") != -1:
35
+ value = value.replace(TEXT_PLACE_HOLDER,
36
+ Utils.get_random_text(length_text=56, space_number=7, with_upper_case=False))
37
+ return value
38
+
39
+ file_uid = basename(input_file)[:basename(input_file).find(".")]
40
+ path = input_file[:input_file.find(file_uid)]
41
+
42
+ input_file_path = "{}{}.gui".format(path, file_uid)
43
+ output_file_path = "{}{}.html".format(path, file_uid)
44
+
45
+ compiler.compile(input_file_path, output_file_path, rendering_function=render_content_with_text)
model.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.nn as nn
2
+ import torch.nn.functional as F
3
+ import torch
4
+
5
+ class ImageEncoder(nn.Module):
6
+
7
+ def __init__(self):
8
+ super(ImageEncoder, self).__init__()
9
+ self.conv1 = nn.Conv2d(3, 32, 3)
10
+ self.conv2 = nn.Conv2d(32, 32, 3)
11
+ self.conv3 = nn.Conv2d(32, 64, 3)
12
+ self.conv4 = nn.Conv2d(64, 64, 3)
13
+ self.conv5 = nn.Conv2d(64, 128, 3)
14
+ self.conv6 = nn.Conv2d(128, 128, 3)
15
+ self.fc1 = nn.Linear(in_features=128*28*28, out_features=1024)
16
+ self.fc2 = nn.Linear(in_features=1024, out_features=1024)
17
+
18
+ def forward(self, x):
19
+ # x -> [-1, 3, 256, 256]
20
+
21
+ x = F.relu(self.conv1(x))
22
+ # x -> [-1, 32, 254, 254]
23
+ x = F.relu(self.conv2(x))
24
+ # x -> [-1, 32, 252, 252]
25
+ x = F.max_pool2d(x, 2)
26
+ # x -> [-1, 32, 126, 126]
27
+
28
+ x = F.relu(self.conv3(x))
29
+ # x -> [-1, 64, 124, 124]
30
+ x = F.relu(self.conv4(x))
31
+ # x -> [-1, 64, 122, 122]
32
+ x = F.max_pool2d(x, 2)
33
+ # x -> [-1, 64, 61, 61]
34
+
35
+ x = F.relu(self.conv5(x))
36
+ # x -> [-1, 128, 59, 59]
37
+ x = F.relu(self.conv6(x))
38
+ # x -> [-1, 128, 57, 57]
39
+ x = F.max_pool2d(x, 2)
40
+ # x -> [-1, 128, 28, 28]
41
+
42
+ x = x.view(-1, 128*28*28)
43
+ x = F.relu(self.fc1(x))
44
+ x = F.relu(self.fc2(x))
45
+ return x
46
+
47
+ class ContextEncoder(nn.Module):
48
+
49
+ def __init__(self):
50
+ super(ContextEncoder, self).__init__()
51
+ self.rnn = nn.RNN(input_size=19, hidden_size=128, num_layers=2, batch_first=True)
52
+
53
+ def forward(self, x, h=None):
54
+ # x -> [-1, seq_size, 19], h -> [num_layer=2,-1, 128]
55
+
56
+ if not h:
57
+ h = torch.zeros((2, x.size(0), 128)).cuda()
58
+
59
+ x, _ = self.rnn(x, h)
60
+ return x
61
+
62
+ class Decoder(nn.Module):
63
+
64
+ def __init__(self):
65
+ super(Decoder, self).__init__()
66
+ self.rnn = nn.RNN(input_size=1024+128, hidden_size=512, num_layers=2, batch_first=True)
67
+ self.l1 = nn.Linear(512, 19)
68
+
69
+ def forward(self, image_feature, context_feature, on_cuda = False, h = None):
70
+ # image_feature -> [-1, 1024], context_feature -> [-1, seq_size=48, 128], h -> [num_layer=2, -1, 512]
71
+ image_feature = image_feature.unsqueeze(1)
72
+ # image_feature -> [-1, 1, 1024]
73
+ image_feature = image_feature.repeat(1, context_feature.size(1), 1)
74
+ # image_feature -> [-1, seq_size, 1024]
75
+ x = torch.cat((image_feature, context_feature), 2)
76
+ # x -> [-1, seq_size=48, 1024+128]
77
+
78
+ if not h:
79
+ h = torch.zeros((2, x.size(0), 512)).cuda()
80
+
81
+ x, _ = self.rnn(x, h)
82
+ x = self.l1(x)
83
+ # x = F.softmax(x, dim=1)
84
+ return x
85
+
86
+ class Pix2Code(nn.Module):
87
+
88
+ def __init__(self):
89
+ super(Pix2Code, self).__init__()
90
+ self.image_encoder = ImageEncoder()
91
+ self.context_encoder = ContextEncoder()
92
+ self.decoder = Decoder()
93
+
94
+ def forward(self, image, context):
95
+ image_feature = self.image_encoder(image)
96
+ context_feature = self.context_encoder(context)
97
+ output = self.decoder(image_feature, context_feature)
98
+ return output
pix2code.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
pix2code.weights.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6ebfa081f5e10ca9d0c58d739b71828856c4aa03f55783898772967d2d2bfa08
3
+ size 422161215
util.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from torch.utils import data
2
+ import torchvision.transforms as transforms
3
+ import os
4
+ import numpy as np
5
+ from PIL import Image
6
+ import pickle
7
+ import torch
8
+
9
+ START_TOKEN = '<START>'
10
+ END_TOKEN = '<END>'
11
+ PLACEHOLDER = ' '
12
+ # CONTEXT_LENGTH = 48
13
+ image_size = 256
14
+
15
+
16
+ class Vocabulary:
17
+
18
+ def __init__(self, file_path):
19
+ self.load_vocab(file_path)
20
+ self.length = len(self.vocab_to_index)
21
+
22
+ def load_vocab(self, file_path):
23
+ self.vocab_to_index = {}
24
+ with open(file_path, 'rb') as vocab_file:
25
+ self.vocab_to_index = pickle.load(vocab_file)
26
+ self.index_to_vocab = {value:key for key, value in self.vocab_to_index.items()}
27
+
28
+ def to_vec(self, word):
29
+ vec = np.zeros(self.length)
30
+ vec[self.vocab_to_index[word]] = 1
31
+ return vec
32
+
33
+ def to_vocab(self, index):
34
+ return self.index_to_vocab[index]
35
+
36
+ class UIDataset(data.Dataset):
37
+
38
+ def __init__(self, file_path, vocab_file_path):
39
+ self.file_path = file_path
40
+ self.paths = []
41
+ self.get_paths()
42
+ self.transform = transforms.Compose([
43
+ transforms.Resize([image_size, image_size]),
44
+ transforms.ToTensor(),
45
+ ])
46
+ self.vocab = Vocabulary(vocab_file_path)
47
+
48
+ def get_paths(self):
49
+ for f in os.listdir(self.file_path):
50
+ if f.find('.gui') != -1:
51
+ file_name = f[:f.find('.gui')]
52
+ if os.path.isfile('{}/{}.png'.format(self.file_path, file_name)):
53
+ self.paths.append(file_name)
54
+
55
+ def __len__(self):
56
+ return(len(self.paths))
57
+
58
+ def __getitem__(self, index):
59
+ image = self.transform(Image.open('{}/{}.png'.format(self.file_path, self.paths[index])))[:-1]
60
+ context, prediction = self.read_gui('{}/{}.gui'.format(self.file_path, self.paths[index]))
61
+ return image, context, prediction
62
+
63
+ def read_gui(self, file_path):
64
+ context = []
65
+ prediction = []
66
+
67
+ # Tokenize the target code and ads start and end token
68
+ token_sequence = [PLACEHOLDER]
69
+ token_sequence.append(START_TOKEN)
70
+ with open(file_path, 'r') as f:
71
+ for line in f:
72
+ line = line.replace(',', ' ,').replace('\n', ' \n')
73
+ tokens = line.split(' ')
74
+ for token in tokens:
75
+ token_sequence.append(token)
76
+ token_sequence.append(END_TOKEN)
77
+
78
+ # Generates cotext prediction pair
79
+ context = token_sequence[:-1]
80
+ prediction = token_sequence[1:]
81
+
82
+ # suffix = [PLACEHOLDER] * CONTEXT_LENGTH
83
+ # a = np.concatenate([suffix, token_sequence])
84
+ # for j in range(len(token_sequence)):
85
+ # # context.append(a[j:j + CONTEXT_LENGTH])
86
+ # context.append(a[j])
87
+ # prediction.append(a[j + CONTEXT_LENGTH])
88
+
89
+ # One hot encoding
90
+ prediction_vec = []
91
+ for word in prediction:
92
+ prediction_vec.append(self.vocab.to_vec(word))
93
+ context_vec = []
94
+ for word in context:
95
+ context_vec.append(self.vocab.to_vec(word))
96
+
97
+ return torch.tensor(context_vec, dtype=torch.float), torch.tensor(prediction_vec, dtype=torch.float)
voc.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cbd452e4523519da80b8dd317f2a2c617f1e41a94594fe18047dd3e6de53f9cd
3
+ size 1287