123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- '''
- KamitKami gives a smaller css to be included with html file for faster website loading times.
- Copyright (C) 2021 Sagar Acharya
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
- '''
- import sys, os, re
- #import soupsieve
- from bs4 import BeautifulSoup
- # changes working directory to script directory
- os.chdir(os.getcwd())
- # get arguments from terminal to list
- names = sys.argv[1:]
- # list which keeps some attributes as they are within css file
- nofilter = ["*", "html", "body", ":root", "head"]
- # checks whether number of arguments are correct
- if len(names)!=2:
- print("Please input only 2 arguments, css filename and html filename")
- sys.exit()
- # checks if files exist in current directory
- if not (os.path.isfile(names[0]+'.css') and os.path.isfile(names[1]+'.html')):
- print("Please input correct names of css and html files. Files do not exist.")
- sys.exit()
- with open(names[0]+'.css') as temp:
- css = temp.read()
- with open(names[1]+'.html') as temp:
- html = temp.read()
- soup = BeautifulSoup(html, 'html.parser')
- def divide_elem_blocks(css_string):
- _import = ["@import" + x + ";" for x in re.findall(r'@import(.*?);', css_string)]
- for i in _import:
- css_string = css_string.replace(i, "")
- selectors = []
- blocks = []
- num_curly = 0
- start = False
-
- record = ["", ""]
- for i in css_string:
- if start:
- if (i == '{'):
- num_curly +=1
- record[1] +=i
- elif (i == '}' and num_curly == 0):
- selectors.append(record[0])
- blocks.append(record[1])
- record = ["", ""]
- start = False
- elif (i == '}' and num_curly > 0):
- num_curly -=1
- else:
- record[1]+=i
- else:
- if (i == '{'):
- start = True
- else:
- record[0]+=i
- if (i == '{' and num_curly == 0):
- start = True
- return _import, selectors, blocks
- # filters C type comments
- css = re.sub('\/\*(\*(?!\/)|[^*])*\*\/', '', css)
- css = css.replace("\n", "")
- # selectors and blocks have same length and correspond to each other
- _import, selectors, blocks = divide_elem_blocks(css)
- notImplemented = 0
- syntaxError = 0
- other = 0
- noFind = 0
- with open(names[1]+"_"+names[0]+".css", 'w') as f:
- for i in _import:
- f.write(i)
- for i in range(len(selectors)):
- if i in nofilter:
- f.write(selectors[i]+'{'+blocks[i]+'}\n')
- continue
- try:
- temp = soup.select(selectors[i])
- if len(temp)>0:
- f.write(selectors[i]+'{'+blocks[i]+'}\n')
- else:
- noFind +=1
- #print("Didn't find "+selectors[i])
- pass
- except:
- f.write(selectors[i]+'{'+blocks[i]+'}\n')
- other +=1
- '''
- print(selectors[i])
- print(soup.select(selectors[i]))
- except NotImplementedError:
- notImplemented +=1
- f.write(selectors[i]+'{'+blocks[i]+'}\n')
- except soupsieve.util.SelectorSyntaxError:
- syntaxError +=1
- f.write(selectors[i]+'{'+blocks[i]+'}\n')
- '''
- #Lines which Beautiful soup cannot detect as css
- print("Error : "+str((notImplemented + syntaxError + other)*100/len(selectors))+ "%")
- #Number of lines of css selectors removed as a % of all css selector lines
- print("Removed : "+str(noFind*100/len(selectors))+ "% lines from css file.")
- #minify
|