import re import streamlit as st from bs4 import BeautifulSoup from pathlib import Path # Streamlit App st.title("HTML to Twig and SCSS Converter") # Functions to parse variables and convert CSS to SCSS def parse_variable_file(variable_file_path): """Parses the SCSS variable file and returns a mapping of color names to their values.""" variables = {} with open(variable_file_path, "r", encoding="utf-8") as file: for line in file: # Match SCSS variables (e.g., `$white: #fff !default;`) match = re.match(r"^\s*\$([\w-]+):\s*(#[a-fA-F0-9]{3,6}|rgba?\(.+?\))", line) if match: variables[match.group(2)] = f"${match.group(1)}" # Color value as key, variable name as value return variables def convert_css_to_scss(css_file_path, variable_mapping, output_scss_path): """Converts CSS file to SCSS by replacing color values with variable names.""" with open(css_file_path, "r", encoding="utf-8") as css_file: css_content = css_file.read() # Replace color values with SCSS variables using the mapping for color, variable in variable_mapping.items(): css_content = css_content.replace(color, variable) # Save the SCSS content to a new file with open(output_scss_path, "w", encoding="utf-8") as scss_file: scss_file.write(css_content) print(f"SCSS file generated: {output_scss_path}") # Functions to convert HTML to Twig and CSS to SCSS def extract_css_and_replace_with_variables(css_content, variables_content): """Replaces CSS properties with SCSS variables.""" try: variables = {} for line in variables_content.splitlines(): match = re.match(r"\$(\w+):\s*(.+);", line) if match: variables[match.group(2).strip()] = match.group(1) for value, var_name in variables.items(): css_content = re.sub(rf"\b{re.escape(value)}\b", f"${{{var_name}}}", css_content) return css_content except Exception as e: st.error(f"Error processing CSS to SCSS: {e}") return None def convert_html_to_twig(html_content): """Converts HTML to Twig format.""" try: soup = BeautifulSoup(html_content, "html.parser") for tag in soup.find_all(): # Replace text with Twig variables if tag.string and tag.string.strip(): tag.string = f"{{{{ {tag.name}_content }}}}" # Example:

{{ h1_content }}

# Replace attributes with Twig variables for attr, value in tag.attrs.items(): tag[attr] = f"{{{{ {attr}_{tag.name} }}}}" # Example: src="{{ src_img }}" # Add comments for Twig variables twig_comments = "\n".join( [ f"" for tag in soup.find_all() if tag.string ] ) return f"{twig_comments}\n{soup.prettify()}" except Exception as e: st.error(f"Error converting HTML to Twig: {e}") return None # File uploaders html_file = st.file_uploader("Upload HTML File", type=["html"], key="html_file") css_file = st.file_uploader("Upload CSS File (Optional)", type=["css"], key="css_file") variables_file = st.file_uploader("Upload SCSS Variables File", type=["scss"], key="variables_file") if html_file and variables_file: variables_content = variables_file.read().decode("utf-8") html_content = html_file.read().decode("utf-8") twig_content = convert_html_to_twig(html_content) if twig_content: st.subheader("Twig Output") st.code(twig_content, language="twig") st.download_button("Download Twig File", data=twig_content, file_name="output.twig", mime="text/plain") if css_file and variables_file: css_content = css_file.read().decode("utf-8") variables_content = variables_file.read().decode("utf-8") variable_mapping = parse_variable_file("variables.scss") # Adjust path if needed output_scss_path = "output.scss" convert_css_to_scss("input.css", variable_mapping, output_scss_path) scss_content = extract_css_and_replace_with_variables(css_content, variables_content) if scss_content: st.subheader("SCSS Output") st.code(scss_content, language="scss") st.download_button("Download SCSS File", data=scss_content, file_name="styles.scss", mime="text/plain")