Task 702: .SVELTE File Format

Task 702: .SVELTE File Format

.SVELTE File Format Specifications

The .SVELTE file format refers to .svelte files used in the Svelte framework for defining components. These are text-based files with a structure that combines JavaScript/TypeScript, CSS, and HTML markup in a superset of HTML.

  1. List of all properties of this file format intrinsic to its file system:
  • Module Script: Optional section containing module-level logic that runs once when the module is evaluated. Defined in a <script module> tag (or <script context="module"> in legacy Svelte 4).
  • Instance Script: Optional section containing instance-level logic that runs for each component instance. Defined in a <script> tag (can include lang="ts" for TypeScript).
  • Markup: Optional section consisting of HTML-like elements and comments outside of script and style tags. This forms the component's template.
  • Style: Optional section containing scoped CSS for the component. Defined in a <style> tag.

These sections can appear in any order, and all are optional.

Two direct download links for files of format .SVELTE:

Ghost blog embedded HTML JavaScript for drag-and-drop .SVELTE file dump:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SVELTE File Dumper</title>
    <style>
        #drop-zone {
            border: 2px dashed #ccc;
            padding: 20px;
            text-align: center;
            margin: 20px;
        }
        #output {
            white-space: pre-wrap;
            margin: 20px;
        }
    </style>
</head>
<body>
    <h1>Drag and Drop .SVELTE File</h1>
    <div id="drop-zone">Drop .svelte file here</div>
    <div id="output"></div>

    <script>
        const dropZone = document.getElementById('drop-zone');
        const output = document.getElementById('output');

        dropZone.addEventListener('dragover', (e) => {
            e.preventDefault();
            dropZone.style.borderColor = '#000';
        });

        dropZone.addEventListener('dragleave', () => {
            dropZone.style.borderColor = '#ccc';
        });

        dropZone.addEventListener('drop', (e) => {
            e.preventDefault();
            dropZone.style.borderColor = '#ccc';
            const file = e.dataTransfer.files[0];
            if (file && file.name.endsWith('.svelte')) {
                const reader = new FileReader();
                reader.onload = (event) => {
                    const text = event.target.result;
                    dumpProperties(text);
                };
                reader.readAsText(file);
            } else {
                output.textContent = 'Please drop a .svelte file.';
            }
        });

        function dumpProperties(text) {
            const parser = new DOMParser();
            const doc = parser.parseFromString(text, 'text/html');
            let moduleScript = '';
            let instanceScript = '';
            let style = '';
            let markup = '';

            // Extract scripts
            const scripts = doc.querySelectorAll('script');
            scripts.forEach(script => {
                const content = script.textContent.trim();
                if (script.hasAttribute('module') || (script.hasAttribute('context') && script.getAttribute('context') === 'module')) {
                    moduleScript = content;
                } else {
                    instanceScript = content;
                }
            });

            // Extract style
            const styleTag = doc.querySelector('style');
            if (styleTag) {
                style = styleTag.textContent.trim();
            }

            // Extract markup: serialize body excluding script and style
            const body = doc.body;
            scripts.forEach(s => s.remove());
            if (styleTag) styleTag.remove();
            markup = body.innerHTML.trim();

            // Output
            output.innerHTML = `
<b>Module Script:</b>\n${moduleScript || 'None'}\n\n
<b>Instance Script:</b>\n${instanceScript || 'None'}\n\n
<b>Markup:</b>\n${markup || 'None'}\n\n
<b>Style:</b>\n${style || 'None'}
            `;
        }
    </script>
</body>
</html>

This can be embedded in a Ghost blog post as raw HTML.

  1. Python class for .SVELTE files:

(Note: Requires beautifulsoup4 for parsing; install via pip install beautifulsoup4 lxml.)

from bs4 import BeautifulSoup
import os

class SvelteFileHandler:
    def __init__(self, filepath):
        self.filepath = filepath
        self.module_script = None
        self.instance_script = None
        self.markup = None
        self.style = None

    def read_and_decode(self):
        with open(self.filepath, 'r', encoding='utf-8') as f:
            text = f.read()
        soup = BeautifulSoup(text, 'lxml')
        
        # Extract scripts
        scripts = soup.find_all('script')
        for script in scripts:
            content = script.string.strip() if script.string else ''
            if script.has_attr('module') or (script.has_attr('context') and script['context'] == 'module'):
                self.module_script = content
            else:
                self.instance_script = content
        
        # Extract style
        style_tag = soup.find('style')
        self.style = style_tag.string.strip() if style_tag and style_tag.string else None
        
        # Extract markup
        for script in scripts:
            script.extract()
        if style_tag:
            style_tag.extract()
        self.markup = str(soup).strip()

    def print_properties(self):
        print("Module Script:", self.module_script or "None")
        print("Instance Script:", self.instance_script or "None")
        print("Markup:", self.markup or "None")
        print("Style:", self.style or "None")

    def write(self, new_filepath=None, module_script=None, instance_script=None, markup=None, style=None):
        filepath = new_filepath or self.filepath
        content = ''
        if module_script is not None:
            content += f'<script module>\n{module_script}\n</script>\n'
        elif self.module_script:
            content += f'<script module>\n{self.module_script}\n</script>\n'
        
        if instance_script is not None:
            content += f'<script>\n{instance_script}\n</script>\n'
        elif self.instance_script:
            content += f'<script>\n{self.instance_script}\n</script>\n'
        
        if markup is not None:
            content += f'{markup}\n'
        elif self.markup:
            content += f'{self.markup}\n'
        
        if style is not None:
            content += f'<style>\n{style}\n</style>\n'
        elif self.style:
            content += f'<style>\n{self.style}\n</style>\n'
        
        with open(filepath, 'w', encoding='utf-8') as f:
            f.write(content)

# Example usage:
# handler = SvelteFileHandler('example.svelte')
# handler.read_and_decode()
# handler.print_properties()
# handler.write('new.svelte', module_script='new module code')
  1. Java class for .SVELTE files:

(Note: Requires Jsoup library; add via Maven: <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.17.2</version></dependency>.)

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class SvelteFileHandler {
    private String filepath;
    private String moduleScript;
    private String instanceScript;
    private String markup;
    private String style;

    public SvelteFileHandler(String filepath) {
        this.filepath = filepath;
    }

    public void readAndDecode() throws IOException {
        String text = new String(Files.readAllBytes(Paths.get(filepath)));
        Document doc = Jsoup.parse(text, "", org.jsoup.parser.Parser.htmlParser());

        // Extract scripts
        Elements scripts = doc.select("script");
        for (Element script : scripts) {
            String content = script.html().trim();
            if (script.hasAttr("module") || (script.hasAttr("context") && script.attr("context").equals("module"))) {
                moduleScript = content;
            } else {
                instanceScript = content;
            }
        }

        // Extract style
        Element styleTag = doc.selectFirst("style");
        style = (styleTag != null) ? styleTag.html().trim() : null;

        // Extract markup
        scripts.remove();
        if (styleTag != null) styleTag.remove();
        markup = doc.html().trim();
    }

    public void printProperties() {
        System.out.println("Module Script: " + (moduleScript != null ? moduleScript : "None"));
        System.out.println("Instance Script: " + (instanceScript != null ? instanceScript : "None"));
        System.out.println("Markup: " + (markup != null ? markup : "None"));
        System.out.println("Style: " + (style != null ? style : "None"));
    }

    public void write(String newFilepath, String newModuleScript, String newInstanceScript, String newMarkup, String newStyle) throws IOException {
        String content = "";
        if (newModuleScript != null) {
            content += "<script module>\n" + newModuleScript + "\n</script>\n";
        } else if (moduleScript != null) {
            content += "<script module>\n" + moduleScript + "\n</script>\n";
        }

        if (newInstanceScript != null) {
            content += "<script>\n" + newInstanceScript + "\n</script>\n";
        } else if (instanceScript != null) {
            content += "<script>\n" + instanceScript + "\n</script>\n";
        }

        if (newMarkup != null) {
            content += newMarkup + "\n";
        } else if (markup != null) {
            content += markup + "\n";
        }

        if (newStyle != null) {
            content += "<style>\n" + newStyle + "\n</style>\n";
        } else if (style != null) {
            content += "<style>\n" + style + "\n</style>\n";
        }

        Files.write(Paths.get(newFilepath != null ? newFilepath : filepath), content.getBytes());
    }

    // Example usage:
    // public static void main(String[] args) throws IOException {
    //     SvelteFileHandler handler = new SvelteFileHandler("example.svelte");
    //     handler.readAndDecode();
    //     handler.printProperties();
    //     handler.write("new.svelte", "new module code", null, null, null);
    // }
}
  1. JavaScript class for .SVELTE files:

(Note: For Node.js; uses built-in fs and DOMParser via jsdom for server-side parsing. Install jsdom via npm install jsdom.)

const fs = require('fs');
const { JSDOM } = require('jsdom');

class SvelteFileHandler {
    constructor(filepath) {
        this.filepath = filepath;
        this.moduleScript = null;
        this.instanceScript = null;
        this.markup = null;
        this.style = null;
    }

    readAndDecode() {
        const text = fs.readFileSync(this.filepath, 'utf-8');
        const dom = new JSDOM(text);
        const doc = dom.window.document;

        // Extract scripts
        const scripts = doc.querySelectorAll('script');
        scripts.forEach(script => {
            const content = script.textContent.trim();
            if (script.hasAttribute('module') || (script.hasAttribute('context') && script.getAttribute('context') === 'module')) {
                this.moduleScript = content;
            } else {
                this.instanceScript = content;
            }
            script.remove();
        });

        // Extract style
        const styleTag = doc.querySelector('style');
        if (styleTag) {
            this.style = styleTag.textContent.trim();
            styleTag.remove();
        }

        // Extract markup
        this.markup = doc.body.innerHTML.trim();
    }

    printProperties() {
        console.log('Module Script:', this.moduleScript || 'None');
        console.log('Instance Script:', this.instanceScript || 'None');
        console.log('Markup:', this.markup || 'None');
        console.log('Style:', this.style || 'None');
    }

    write(newFilepath = this.filepath, { moduleScript, instanceScript, markup, style } = {}) {
        let content = '';
        if (moduleScript !== undefined) {
            content += `<script module>\n${moduleScript}\n</script>\n`;
        } else if (this.moduleScript) {
            content += `<script module>\n${this.moduleScript}\n</script>\n`;
        }

        if (instanceScript !== undefined) {
            content += `<script>\n${instanceScript}\n</script>\n`;
        } else if (this.instanceScript) {
            content += `<script>\n${this.instanceScript}\n</script>\n`;
        }

        if (markup !== undefined) {
            content += `${markup}\n`;
        } else if (this.markup) {
            content += `${this.markup}\n`;
        }

        if (style !== undefined) {
            content += `<style>\n${style}\n</style>\n`;
        } else if (this.style) {
            content += `<style>\n${this.style}\n</style>\n`;
        }

        fs.writeFileSync(newFilepath, content, 'utf-8');
    }
}

// Example usage:
// const handler = new SvelteFileHandler('example.svelte');
// handler.readAndDecode();
// handler.printProperties();
// handler.write('new.svelte', { moduleScript: 'new module code' });
  1. C class for .SVELTE files (implemented in C++ for class support; uses basic string operations for parsing, no external libraries):
#include <iostream>
#include <fstream>
#include <string>
#include <regex>

class SvelteFileHandler {
private:
    std::string filepath;
    std::string module_script;
    std::string instance_script;
    std::string markup;
    std::string style;

public:
    SvelteFileHandler(const std::string& fp) : filepath(fp) {}

    void read_and_decode() {
        std::ifstream file(filepath);
        if (!file) {
            std::cerr << "Failed to open file." << std::endl;
            return;
        }
        std::string text((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());

        // Simple regex-based extraction (not perfect, but functional for basic cases)
        std::regex module_regex(R"(<script\s+module>[\s\S]*?</script>)");
        std::smatch match;
        if (std::regex_search(text, match, module_regex)) {
            module_script = match[0].str().substr(15, match[0].str().length() - 24); // Strip tags
        } else {
            std::regex legacy_regex(R"(<script\s+context="module">[\s\S]*?</script>)");
            if (std::regex_search(text, match, legacy_regex)) {
                module_script = match[0].str().substr(26, match[0].str().length() - 35);
            }
        }

        std::regex instance_regex(R"(<script(?! module| context="module")>[\s\S]*?</script>)");
        if (std::regex_search(text, match, instance_regex)) {
            instance_script = match[0].str().substr(8, match[0].str().length() - 17);
        }

        std::regex style_regex(R"(<style>[\s\S]*?</style>)");
        if (std::regex_search(text, match, style_regex)) {
            style = match[0].str().substr(7, match[0].str().length() - 15);
        }

        // Markup: rough approximation by removing matched sections
        std::string temp = text;
        temp = std::regex_replace(temp, module_regex, "");
        temp = std::regex_replace(temp, legacy_regex, "");
        temp = std::regex_replace(temp, instance_regex, "");
        temp = std::regex_replace(temp, style_regex, "");
        markup = temp;

        // Trim whitespaces
        module_script = trim(module_script);
        instance_script = trim(instance_script);
        style = trim(style);
        markup = trim(markup);
    }

    void print_properties() {
        std::cout << "Module Script: " << (module_script.empty() ? "None" : module_script) << std::endl;
        std::cout << "Instance Script: " << (instance_script.empty() ? "None" : instance_script) << std::endl;
        std::cout << "Markup: " << (markup.empty() ? "None" : markup) << std::endl;
        std::cout << "Style: " << (style.empty() ? "None" : style) << std::endl;
    }

    void write(const std::string& new_filepath = "", const std::string& new_module = "", const std::string& new_instance = "", const std::string& new_markup = "", const std::string& new_style = "") {
        std::string fp = new_filepath.empty() ? filepath : new_filepath;
        std::ofstream out(fp);
        if (!out) {
            std::cerr << "Failed to write file." << std::endl;
            return;
        }

        std::string m = new_module.empty() ? module_script : new_module;
        if (!m.empty()) {
            out << "<script module>\n" << m << "\n</script>\n";
        }

        std::string i = new_instance.empty() ? instance_script : new_instance;
        if (!i.empty()) {
            out << "<script>\n" << i << "\n</script>\n";
        }

        std::string mk = new_markup.empty() ? markup : new_markup;
        if (!mk.empty()) {
            out << mk << "\n";
        }

        std::string s = new_style.empty() ? style : new_style;
        if (!s.empty()) {
            out << "<style>\n" << s << "\n</style>\n";
        }
    }

private:
    std::string trim(const std::string& str) {
        size_t first = str.find_first_not_of(" \n\r\t");
        if (first == std::string::npos) return "";
        size_t last = str.find_last_not_of(" \n\r\t");
        return str.substr(first, (last - first + 1));
    }
};

// Example usage:
// int main() {
//     SvelteFileHandler handler("example.svelte");
//     handler.read_and_decode();
//     handler.print_properties();
//     handler.write("new.svelte", "new module code");
//     return 0;
// }