自创编程语言之long语言

go语言写long解释器已开源

合作交流QQ1842810327 微信1842810327

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("请提供源文件名作为参数.")
		return
	}

	sourceFileName := os.Args[1]
	sourceFile, err := os.Open(sourceFileName)
	if err != nil {
		fmt.Println("Error opening source file:", err)
		return
	}
	defer sourceFile.Close()
	fmt.Println("成功打开文件:", sourceFileName)

	outputFileName := strings.TrimSuffix(sourceFileName, ".txt") + ".html"
	outputFile, err := os.Create(outputFileName)
	if err != nil {
		fmt.Println("Error creating output file:", err)
		return
	}
	defer outputFile.Close()
	fmt.Println("成功创建文件:", outputFileName)

	// 写入 HTML 文件的头部
	_, err = outputFile.WriteString("<html>\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>合成后的 HTML</title>\n<style>\n.tab {display: none;}\n.active {display: block;}\n.tab-button {cursor: pointer; margin-right: 10px;}\n.tab-container {position: fixed; bottom: 0; left: 0; right: 0; display: flex; justify-content: space-around; background-color: #f1f1f1; padding: 10px; box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);}\n</style>\n</head>\n<body>\n")
	if err != nil {
		fmt.Println("Error writing to output file:", err)
		return
	}

	reader := bufio.NewReader(sourceFile)

	var tabs []string
	var tabContents = make(map[string]string)

	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			break
		}
		line = strings.TrimSpace(line)

		if strings.Contains(line, "{") { // 处理 tab 内容
			tabName := extractValue(line)
			content := parseTabContent(reader) // 解析 tab 内容
			tabContents[tabName] = content
			tabs = append(tabs, tabName)
		} else {
			html := processLine(line, &tabs)
			if html != "" {
				_, err = outputFile.WriteString(html + "\n")
				if err != nil {
					fmt.Println("Error writing to output file:", err)
					return
				}
			}
		}
	}

	// 生成 tab 按钮和内容
	if len(tabs) > 0 {
		_, err = outputFile.WriteString("<div class=\"tab-container\">\n")
		for _, tab := range tabs {
			_, err = outputFile.WriteString(fmt.Sprintf("<span class=\"tab-button\" onclick=\"showTab('%s')\">%s</span>\n", tab, tab))
		}
		_, err = outputFile.WriteString("</div>\n")
		if err != nil {
			fmt.Println("Error writing to output file:", err)
			return
		}

		for tabName, content := range tabContents {
			_, err = outputFile.WriteString(fmt.Sprintf("<div class=\"tab\" id=\"%s\">%s</div>\n", tabName, content))
			if err != nil {
				fmt.Println("Error writing to output file:", err)
				return
			}
		}
	}

	// 在文件末尾写入 JavaScript 代码和关闭 HTML
	_, err = outputFile.WriteString(`
<script>
function showTab(tabName) {
	var i, tab, buttons;
	tab = document.getElementsByClassName("tab");
	for (i = 0; i < tab.length; i++) {
		tab[i].style.display = "none";  
	}
	document.getElementById(tabName).style.display = "block";  
}
</script>
</body>\n</html>`)
	if err != nil {
		fmt.Println("Error writing to output file:", err)
		return
	}

	fmt.Printf("HTML 文件生成成功: %s\n", outputFileName)
}

func parseTabContent(reader *bufio.Reader) string {
	var content string
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			break
		}
		line = strings.TrimSpace(line)
		if strings.HasSuffix(line, "};") {
			break
		}
		content += processLine(line, nil) + "\n"
	}
	return content
}

func processLine(line string, tabs *[]string) string {
	if strings.HasPrefix(line, "button(") {
		return generateButton(line)
	} else if strings.HasPrefix(line, "text(") {
		return generateText(line)
	} else if strings.HasPrefix(line, "input(") {
		return generateInputField(line)
	} else if strings.HasPrefix(line, "tab(") {
		return generateTab(line, tabs)
	} else if strings.HasPrefix(line, "image(") {
		return generateImage(line)
	} else if strings.HasPrefix(line, "music(") {
		return generateMusic(line)
	} else if strings.HasPrefix(line, "video(") {
		return generateVideo(line)
	}

	// 处理其他类型的内容
	parts := strings.Split(line, ".")
	if len(parts) == 0 {
		return ""
	}

	title := parts[0]
	style := extractStyles(parts[1:])

	if style != "" {
		html := fmt.Sprintf("<div style=\"%s\" class=\"tab\" id=\"%s\">%s</div>", style, title, title)
		return html
	}
	return ""
}

func generateImage(line string) string {
	imageUrl := extractValue(line)
	style := extractStyles(strings.Split(line, ".")[1:])
	if imageUrl == "" {
		return ""
	}
	return fmt.Sprintf("<img src=\"%s\" style=\"%s; width: %s; height: %s;\">", imageUrl, style)
}

func generateMusic(line string) string {
	musicUrl := extractValue(line)
	style := extractStyles(strings.Split(line, ".")[1:])
	if musicUrl == "" {
		return ""
	}
	return fmt.Sprintf("<audio controls style=\"%s\"><source src=\"%s\" type=\"audio/mpeg\">你的浏览器不支持音频元素。</audio>", style, musicUrl)
}

func generateVideo(line string) string {
	videoUrl := extractValue(line)
	style := extractStyles(strings.Split(line, ".")[1:])
	if videoUrl == "" {
		return ""
	}
	return fmt.Sprintf("<video controls style=\"%s\"><source src=\"%s\" type=\"video/mp4\">你的浏览器不支持视频元素。</video>", style, videoUrl)
}

func generateText(line string) string {
	textContent := extractValue(line)
	style := extractStyles(strings.Split(line, ".")[1:])
	if textContent == "" {
		return ""
	}
	return fmt.Sprintf("<div style=\"%s\">%s</div>", style, textContent)
}

func generateButton(line string) string {
	label := extractValue(line)
	style := extractStyles(strings.Split(line, ".")[1:])
	alertMessage := extractAlertMessage(line)
	if label == "" {
		return ""
	}
	if alertMessage != "" {
		return fmt.Sprintf("<button style=\"%s\" onclick=\"alert('%s')\">%s</button>", style, escapeJavaScript(alertMessage), label)
	}
	return fmt.Sprintf("<button style=\"%s\">%s</button>", style, label)
}

// escapeJavaScript 函数用于处理字符串中的特殊字符
func escapeJavaScript(message string) string {
	message = strings.ReplaceAll(message, "'", "\\'")
	message = strings.ReplaceAll(message, "\"", "\\\"")
	message = strings.ReplaceAll(message, "\n", "\\n")
	return message
}

func generateInputField(line string) string {
	placeholder := extractValue(line)
	style := extractStyles(strings.Split(line, ".")[1:])
	if placeholder == "" {
		return ""
	}
	return fmt.Sprintf("<input type=\"text\" placeholder=\"%s\" style=\"%s\">", placeholder, style)
}

func generateTab(line string, tabs *[]string) string {
	tabName := extractValue(line)
	style := extractStyles(strings.Split(line, ".")[1:])
	if tabName != "" {
		*tabs = append(*tabs, tabName)
		return fmt.Sprintf("<div style=\"%s\" class=\"tab\" id=\"%s\">%s 内容</div>", style, tabName, tabName)
	}
	return ""
}

func extractStyles(parts []string) string {
	style := ""
	for _, part := range parts {
		if strings.HasPrefix(part, "fontSize(") {
			size := extractValue(part)
			style += fmt.Sprintf("font-size: %s;", size)
		} else if strings.HasPrefix(part, "color(") {
			color := extractValue(part)
			style += fmt.Sprintf("color: %s;", color)
		} else if strings.HasPrefix(part, "left(") {
			left := extractValue(part)
			style += fmt.Sprintf("margin-left: %s;", left)
		} else if strings.HasPrefix(part, "right(") {
			right := extractValue(part)
			style += fmt.Sprintf("margin-right: %s;", right)
		} else if strings.HasPrefix(part, "top(") {
			top := extractValue(part)
			style += fmt.Sprintf("margin-top: %s;", top)
		} else if strings.HasPrefix(part, "bottom(") {
			bottom := extractValue(part)
			style += fmt.Sprintf("margin-bottom: %s;", bottom)
		} else if strings.HasPrefix(part, "width(") {
			width := extractValue(part)
			style += fmt.Sprintf("width: %s;", width)
		} else if strings.HasPrefix(part, "height(") {
			height := extractValue(part)
			style += fmt.Sprintf("height: %s;", height)
		}
	}
	return style
}

func extractValue(part string) string {
	start := strings.Index(part, "(")
	end := strings.Index(part, ")")
	if start != -1 && end != -1 && end > start {
		return strings.TrimSpace(part[start+1 : end])
	}
	return ""
}

func extractAlertMessage(line string) string {
	if strings.Contains(line, "alert(") {
		// 找到 alert( 的位置
		start := strings.Index(line, "alert(") + len("alert(")
		// 在 alert( 之后找到对应的 )
		end := strings.Index(line[start:], ")") + start
		if end > start {
			// 提取 alert 的内容
			return line[start:end]
		}
	}
	return ""
}

龙long语言代码 source.txt 见单词顾名思义 还是很容易看的

目前实现了tab组件 image组件 music组件 video组件 text组件 button组件 input组件

tab(首页).router(home).fontSize(20px).color(#FF00FF).left(50px).right(50px).top(50px).bottom(0px){

    image(https://fastly.picsum.photos/id/740/200/200.jpg?hmac=9ZHqyCz7Gy7V9lyQcKw8m1VAVXW6mjx26txirRYVaSc).width(100px).height(100px).left(50px).right(50px).top(50px).bottom(50px);
    music(http://downsc.chinaz.net/Files/DownLoad/sound1/201906/11582.mp3).width(500px).height(100px).left(50px).right(50px).top(50px).bottom(50px)
    video(https://media.w3.org/2010/05/sintel/trailer.mp4).width(500px).height(500px).left(50px).right(50px).top(50px).bottom(50px)

};

tab(动态).router(dong).fontSize(20px).color(#FF00FF).left(50px).right(50px).top(50px).bottom(0px){

    text(标题2).fontSize(50px).color(#FF00FF).left(10px).right(10px).top(10px).bottom(10px);
    button(点击2).fontSize(20px).color(#FF00FF).left(50px).right(50px).top(50px).bottom(50px).alert(hello worid);
    input(请输入内容).fontSize(18px).color(#000000).left(10px).right(10px).top(10px).bottom(10px);

};

tab(会员).router(huiyuan).fontSize(20px).color(#FF00FF).left(50px).right(50px).top(50px).bottom(0px){

    text(标题3).fontSize(50px).color(#FF00FF).left(10px).right(10px).top(10px).bottom(10px);
    button(点击3).fontSize(20px).color(#FF00FF).left(50px).right(50px).top(50px).bottom(50px).alert(hello worid);
    input(请输入内容).fontSize(18px).color(#000000).left(10px).right(10px).top(10px).bottom(10px);

};

tab(我的).router(wode).fontSize(20px).color(#FF00FF).left(50px).right(50px).top(50px).bottom(0px){

    text(标题4).fontSize(50px).color(#FF00FF).left(10px).right(10px).top(10px).bottom(10px);
    button(点击4).fontSize(20px).color(#FF00FF).left(50px).right(50px).top(50px).bottom(50px).alert(hello worid);
    input(请输入内容).fontSize(18px).color(#000000).left(10px).right(10px).top(10px).bottom(10px);
};

//source.txt               go build -o long.exe main.go          .\long.exe .\source.txt

使用 go build -o long.exe main.go 编程为解释器 long.exe

cmd中 .\long.exe .\source.txt 生成为source.html文件

生成后的文件如下

source.html

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>合成后的 HTML</title>
<style>
.tab {display: none;}
.active {display: block;}
.tab-button {cursor: pointer; margin-right: 10px;}
.tab-container {position: fixed; bottom: 0; left: 0; right: 0; display: flex; justify-content: space-around; background-color: #f1f1f1; padding: 10px; box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);}
</style>
</head>
<body>
<div class="tab-container">
<span class="tab-button" onclick="showTab('首页')">首页</span>
<span class="tab-button" onclick="showTab('动态')">动态</span>
<span class="tab-button" onclick="showTab('会员')">会员</span>
<span class="tab-button" onclick="showTab('我的')">我的</span>
</div>
<div class="tab" id="首页">
<img src="https://fastly.picsum.photos/id/740/200/200.jpg?hmac=9ZHqyCz7Gy7V9lyQcKw8m1VAVXW6mjx26txirRYVaSc" style="width: 100px;height: 100px;margin-left: 50px;margin-right: 50px;margin-top: 50px;margin-bottom: 50px;; width: %!s(MISSING); height: %!s(MISSING);">
<audio controls style="width: 500px;height: 100px;margin-left: 50px;margin-right: 50px;margin-top: 50px;margin-bottom: 50px;"><source src="http://downsc.chinaz.net/Files/DownLoad/sound1/201906/11582.mp3" type="audio/mpeg">你的浏览器不支持音频元素。</audio>
<video controls style="width: 500px;height: 500px;margin-left: 50px;margin-right: 50px;margin-top: 50px;margin-bottom: 50px;"><source src="https://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4">你的浏览器不支持视频元素。</video>

</div>
<div class="tab" id="动态">
<div style="font-size: 50px;color: #FF00FF;margin-left: 10px;margin-right: 10px;margin-top: 10px;margin-bottom: 10px;">标题2</div>
<button style="font-size: 20px;color: #FF00FF;margin-left: 50px;margin-right: 50px;margin-top: 50px;margin-bottom: 50px;" onclick="alert('hello worid')">点击2</button>
<input type="text" placeholder="请输入内容" style="font-size: 18px;color: #000000;margin-left: 10px;margin-right: 10px;margin-top: 10px;margin-bottom: 10px;">

</div>
<div class="tab" id="会员">
<div style="font-size: 50px;color: #FF00FF;margin-left: 10px;margin-right: 10px;margin-top: 10px;margin-bottom: 10px;">标题3</div>
<button style="font-size: 20px;color: #FF00FF;margin-left: 50px;margin-right: 50px;margin-top: 50px;margin-bottom: 50px;" onclick="alert('hello worid')">点击3</button>
<input type="text" placeholder="请输入内容" style="font-size: 18px;color: #000000;margin-left: 10px;margin-right: 10px;margin-top: 10px;margin-bottom: 10px;">

</div>
<div class="tab" id="我的">
<div style="font-size: 50px;color: #FF00FF;margin-left: 10px;margin-right: 10px;margin-top: 10px;margin-bottom: 10px;">标题4</div>
<button style="font-size: 20px;color: #FF00FF;margin-left: 50px;margin-right: 50px;margin-top: 50px;margin-bottom: 50px;" onclick="alert('hello worid')">点击4</button>
<input type="text" placeholder="请输入内容" style="font-size: 18px;color: #000000;margin-left: 10px;margin-right: 10px;margin-top: 10px;margin-bottom: 10px;">
</div>

<script>
function showTab(tabName) {
	var i, tab, buttons;
	tab = document.getElementsByClassName("tab");
	for (i = 0; i < tab.length; i++) {
		tab[i].style.display = "none";  
	}
	document.getElementById(tabName).style.display = "block";  
}
</script>
</body>\n</html>

运行后的效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王家视频教程图书馆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值