diff --git a/.gitignore b/.gitignore
index 024feda..4b95f64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,15 +82,3 @@ chsrc-dbgsym_*.ddeb
chsrc_*.build
chsrc_*.buildinfo
chsrc_*.changes
-
-
-
-##############################
-# rawstr4c
-##############################
-.precomp
-
-*.tar.gz
-
-tool/rawstr4c/test/fixture/rawstr4c.c
-tool/rawstr4c/test/fixture/rawstr4c.h
diff --git a/tool/rawstr4c/.gitignore b/tool/rawstr4c/.gitignore
deleted file mode 100644
index ceca081..0000000
--- a/tool/rawstr4c/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-# 2025-07-21
-#
-# 这个放在内部的 .gitignore 文件也是能起作用的
-#
-# 但是 Raku 很容易不小心生成 .precomp 目录
-#
-# 所以我们还是把所有 ignore 配置放在项目根目录下吧
diff --git a/tool/rawstr4c/LICENSE b/tool/rawstr4c/LICENSE
deleted file mode 100644
index f29c7fb..0000000
--- a/tool/rawstr4c/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- The Artistic License 2.0
-
- Copyright (c) 2000-2006, The Perl Foundation.
-
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-Preamble
-
-This license establishes the terms under which a given free software
-Package may be copied, modified, distributed, and/or redistributed.
-The intent is that the Copyright Holder maintains some artistic
-control over the development of that Package while still keeping the
-Package available as open source and free software.
-
-You are always permitted to make arrangements wholly outside of this
-license directly with the Copyright Holder of a given Package. If the
-terms of this license do not permit the full use that you propose to
-make of the Package, you should contact the Copyright Holder and seek
-a different licensing arrangement.
-
-Definitions
-
- "Copyright Holder" means the individual(s) or organization(s)
- named in the copyright notice for the entire Package.
-
- "Contributor" means any party that has contributed code or other
- material to the Package, in accordance with the Copyright Holder's
- procedures.
-
- "You" and "your" means any person who would like to copy,
- distribute, or modify the Package.
-
- "Package" means the collection of files distributed by the
- Copyright Holder, and derivatives of that collection and/or of
- those files. A given Package may consist of either the Standard
- Version, or a Modified Version.
-
- "Distribute" means providing a copy of the Package or making it
- accessible to anyone else, or in the case of a company or
- organization, to others outside of your company or organization.
-
- "Distributor Fee" means any fee that you charge for Distributing
- this Package or providing support for this Package to another
- party. It does not mean licensing fees.
-
- "Standard Version" refers to the Package if it has not been
- modified, or has been modified only in ways explicitly requested
- by the Copyright Holder.
-
- "Modified Version" means the Package, if it has been changed, and
- such changes were not explicitly requested by the Copyright
- Holder.
-
- "Original License" means this Artistic License as Distributed with
- the Standard Version of the Package, in its current version or as
- it may be modified by The Perl Foundation in the future.
-
- "Source" form means the source code, documentation source, and
- configuration files for the Package.
-
- "Compiled" form means the compiled bytecode, object code, binary,
- or any other form resulting from mechanical transformation or
- translation of the Source form.
-
-
-Permission for Use and Modification Without Distribution
-
-(1) You are permitted to use the Standard Version and create and use
-Modified Versions for any purpose without restriction, provided that
-you do not Distribute the Modified Version.
-
-
-Permissions for Redistribution of the Standard Version
-
-(2) You may Distribute verbatim copies of the Source form of the
-Standard Version of this Package in any medium without restriction,
-either gratis or for a Distributor Fee, provided that you duplicate
-all of the original copyright notices and associated disclaimers. At
-your discretion, such verbatim copies may or may not include a
-Compiled form of the Package.
-
-(3) You may apply any bug fixes, portability changes, and other
-modifications made available from the Copyright Holder. The resulting
-Package will still be considered the Standard Version, and as such
-will be subject to the Original License.
-
-
-Distribution of Modified Versions of the Package as Source
-
-(4) You may Distribute your Modified Version as Source (either gratis
-or for a Distributor Fee, and with or without a Compiled form of the
-Modified Version) provided that you clearly document how it differs
-from the Standard Version, including, but not limited to, documenting
-any non-standard features, executables, or modules, and provided that
-you do at least ONE of the following:
-
- (a) make the Modified Version available to the Copyright Holder
- of the Standard Version, under the Original License, so that the
- Copyright Holder may include your modifications in the Standard
- Version.
-
- (b) ensure that installation of your Modified Version does not
- prevent the user installing or running the Standard Version. In
- addition, the Modified Version must bear a name that is different
- from the name of the Standard Version.
-
- (c) allow anyone who receives a copy of the Modified Version to
- make the Source form of the Modified Version available to others
- under
-
- (i) the Original License or
-
- (ii) a license that permits the licensee to freely copy,
- modify and redistribute the Modified Version using the same
- licensing terms that apply to the copy that the licensee
- received, and requires that the Source form of the Modified
- Version, and of any works derived from it, be made freely
- available in that license fees are prohibited but Distributor
- Fees are allowed.
-
-
-Distribution of Compiled Forms of the Standard Version
-or Modified Versions without the Source
-
-(5) You may Distribute Compiled forms of the Standard Version without
-the Source, provided that you include complete instructions on how to
-get the Source of the Standard Version. Such instructions must be
-valid at the time of your distribution. If these instructions, at any
-time while you are carrying out such distribution, become invalid, you
-must provide new instructions on demand or cease further distribution.
-If you provide valid instructions or cease distribution within thirty
-days after you become aware that the instructions are invalid, then
-you do not forfeit any of your rights under this license.
-
-(6) You may Distribute a Modified Version in Compiled form without
-the Source, provided that you comply with Section 4 with respect to
-the Source of the Modified Version.
-
-
-Aggregating or Linking the Package
-
-(7) You may aggregate the Package (either the Standard Version or
-Modified Version) with other packages and Distribute the resulting
-aggregation provided that you do not charge a licensing fee for the
-Package. Distributor Fees are permitted, and licensing fees for other
-components in the aggregation are permitted. The terms of this license
-apply to the use and Distribution of the Standard or Modified Versions
-as included in the aggregation.
-
-(8) You are permitted to link Modified and Standard Versions with
-other works, to embed the Package in a larger work of your own, or to
-build stand-alone binary or bytecode versions of applications that
-include the Package, and Distribute the result without restriction,
-provided the result does not expose a direct interface to the Package.
-
-
-Items That are Not Considered Part of a Modified Version
-
-(9) Works (including, but not limited to, modules and scripts) that
-merely extend or make use of the Package, do not, by themselves, cause
-the Package to be a Modified Version. In addition, such works are not
-considered parts of the Package itself, and are not subject to the
-terms of this license.
-
-
-General Provisions
-
-(10) Any use, modification, and distribution of the Standard or
-Modified Versions is governed by this Artistic License. By using,
-modifying or distributing the Package, you accept this license. Do not
-use, modify, or distribute the Package, if you do not accept this
-license.
-
-(11) If your Modified Version has been derived from a Modified
-Version made by someone other than you, you are nevertheless required
-to ensure that your Modified Version complies with the requirements of
-this license.
-
-(12) This license does not grant you the right to use any trademark,
-service mark, tradename, or logo of the Copyright Holder.
-
-(13) This license includes the non-exclusive, worldwide,
-free-of-charge patent license to make, have made, use, offer to sell,
-sell, import and otherwise transfer the Package with respect to any
-patent claims licensable by the Copyright Holder that are necessarily
-infringed by the Package. If you institute patent litigation
-(including a cross-claim or counterclaim) against any party alleging
-that the Package constitutes direct or contributory patent
-infringement, then this Artistic License to you shall terminate on the
-date that such litigation is filed.
-
-(14) Disclaimer of Warranty:
-THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
-IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
-LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tool/rawstr4c/META6.json b/tool/rawstr4c/META6.json
deleted file mode 100644
index 2aeac7a..0000000
--- a/tool/rawstr4c/META6.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "rawstr4c",
- "version": "0.2.1",
- "description": "Raw strings for the C programming language",
-
- "authors": ["Aoran Zeng"],
- "auth": "zef:ccmywish",
- "license": "Artistic-2.0",
-
- "tags": ["c"],
- "support": {
- "homepage": "https://github.com/RubyMetric/chsrc/blob/dev/tool/rawstr4c",
- "source": "https://github.com/RubyMetric/chsrc.git",
- "bugtracker": "https://github.com/RubyMetric/chsrc/issues"
- },
-
- "raku": "6.*",
- "resources": [],
- "depends": [],
- "build-depends": [],
- "test-depends": [],
- "provides": {
- "Rawstr4c::Parser": "lib/Rawstr4c/Parser.rakumod",
- "Rawstr4c::Config": "lib/Rawstr4c/Config.rakumod",
- "Rawstr4c::Generator": "lib/Rawstr4c/Generator.rakumod",
- "Rawstr4c::Version": "lib/Rawstr4c/Version.rakumod"
- }
-}
diff --git a/tool/rawstr4c/README.md b/tool/rawstr4c/README.md
deleted file mode 100644
index 10d8c3f..0000000
--- a/tool/rawstr4c/README.md
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-# rawstr4c
-
-Use this tool when you need to write complex C language strings.
-
-```bash
-$ rawstr4c --help
-```
-
-
-
-
-
-## Convention
-
-A configuration file should use this order:
-
-1. section title
-2. description of the variable
-3. configuration block (configblock)
-4. configuration block (configblock) comments
-5. code block (codeblock) (raw string)
-6. comments for the content of the code block (codeblock)
-
-
-
-
-
-## Configuration Syntax
-
-```markdown
-
-- config-item1 = `:mode`
-
-- config-item2 = `true|false|yes|no`
-
-- config-item3 = `string value`
-
-```
-
-Configuration items always start with `-`, followed by the configuration item name and an `=`, and the right-hand value must be wrapped with ``` `` ```.
-
-Note: if the value is not arbitrarily given by the user, it should be set as a mode type, using `:` as a prefix.
-
-
-
-
-
-## Configuration Items
-
-Note: unless otherwise specified, the first item is the default value
-
-- output =
-
- - `:terminal` = output to terminal
- - `:macro` = output as a `.h` file, defined as macro
- - `:global-variable` = output a `.h` file and corresponding `.c` file, defined as global variable
- - `:global-variable-only-header` = output only as a `.h` file, defined as global variable
-
-- ~~output-file~~ = (not yet implemented)
-
- Custom generated header filename, default value is `rawstr4c.h`
-
-- translate =
-
- - `:escape` = escape only
- - `:oct` = octal
- - `:hex` = hexadecimal
-
-- postfix =
-
- - `:use-language` = use the language of the codeblock
- - `your string` = use a custom string as suffix
-
-- name =
-
- Generated variable name, will include prefix and suffix by default. If this configuration item is not given, the section title will be used
-
-- name-literally = `false` | `true`
-
- Ignore other configuration items and directly use `name` as the variable name
-
-- namespace =
-
- Will serve as a prefix after `prefix` and before variable name `name`, affecting the next level section
-
-- keep-prefix = `true` | `false`
-
- Whether the variable name uses prefix
-
-- keep-postfix = `true` | `false`
-
- Whether the variable name uses postfix
diff --git a/tool/rawstr4c/bin/rawstr4c b/tool/rawstr4c/bin/rawstr4c
deleted file mode 100644
index 48e6dfc..0000000
--- a/tool/rawstr4c/bin/rawstr4c
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env raku
-# ---------------------------------------------------------------
-# Copyright © 2025-2025 Aoran Zeng
-# SPDX-License-Identifier: Artistic-2.0
-# ---------------------------------------------------------------
-# File Name : rawstr4c.raku
-# File Authors : Aoran Zeng
-# Contributors : Nul None
-# Created On : <2025-07-12>
-# Last Modified : <2025-07-16>
-#
-# rawstr4c:
-#
-# Raw strings for the C programming language
-# ---------------------------------------------------------------
-
-use Rawstr4c::Parser;
-use Rawstr4c::Generator;
-use Rawstr4c::Version;
-
-sub USAGE() {
- print qq:to/END/;
- rawstr4c: Raw Strings for C (Artistic-2.0) v{Rawstr4c::Version::VERSION}-{Rawstr4c::Version::RELEASE_DATE}
-
- Usage: rawstr4c [options]
-
- Arguments:
- FILE.md Process a specific markdown file
- DIR Process rawstr4c.md file in the given directory
-
- Options:
- -d|--debug Show debug information during processing
- Value can be [generator|parser]. Default to generator.
-
- -v|--version Show version information
-
- -h|--help Show this help message
-
- END
-}
-
-
-sub MAIN(
- Str $input-path?,
- # 如果是 Str 类型,则 --debug 缺少命令行参数
- # 如果是 Any 类型,则可以直接使用 --debug,值为 True
- Any :$debug,
- Any :$version,
- :$d, :$v, :$h
-)
-{
- if ($version || $v) {
- print Rawstr4c::Version::VERSION_CONTENT_FOR_-version;
- exit(0);
- }
-
- if ($h) {
- USAGE;
- exit(0);
- }
-
- if (!$input-path) {
- USAGE;
- exit(0);
- }
-
- my $markdown-file;
-
- if $input-path.IO.d {
- $markdown-file = $input-path.IO.add("rawstr4c.md");
- unless $markdown-file.e {
- # 也可以 warn
- note "Error: No 'rawstr4c.md' file found in directory '$input-path'";
- exit(1);
- }
- }
- elsif $input-path.IO.f {
- $markdown-file = $input-path.IO;
- } else {
- note "Error: '$input-path' is neither a file nor a directory";
- exit(1);
- }
-
- my $parser = Rawstr4c::Parser::Parser.new($markdown-file.Str);
- $parser.parse;
-
- my $generator = Rawstr4c::Generator::Generator.new($parser);
-
- if ($debug.defined) {
- given $debug {
- when 'parser' {$parser.debug;}
- default {$generator.debug;}
- }
- }
-
- if ($d.defined) {
- given $d {
- when 'parser' {$parser.debug;}
- default {$generator.debug;}
- }
- }
-
- $generator.generate;
-}
diff --git a/tool/rawstr4c/doc/01-Develop.md b/tool/rawstr4c/doc/01-Develop.md
deleted file mode 100644
index 1b13081..0000000
--- a/tool/rawstr4c/doc/01-Develop.md
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
-# Develop `rawstr4c`
-
-## Dependencies and Dev environment
-
-Please install these first:
-
- 1. [rakudo]
- 2. [just]
-
-
-
-
-
-## Get code
-
-**Please make sure to use the dev branch for development**
-
-```bash
-git clone https://gitee.com/RubyMetric/chsrc.git -b dev
-```
-
-
-
-
-
-## Run
-
-**For convenience, when developing, we only use `just` to invoke it.**
-
-> [!IMPORTANT]
-> When developing `rawstr4c` and maintaining `chsrc`,
-> we must always give a path relative to the root directory of the whole `chsrc` project!
-> This is because `just` will switch back to the project root directory by itself.
-
-```bash
-# Now we've already cd into the current dir
-cd src/recipe
-# Still have to use path relative to root!!!
-just rawstr4c ./src/recipe/ware
-```
-
-```bash
-just rawstr4c
-```
-
-We can install the distribution, by this way, we don't need `just`.
-
-```bash
-zef install .
-
-rawstr4c --help
-```
-
-And therefore no such limitations mentioned above!
-
-```bash
-cd src/recipe
-# No need to to use path relative to root now!!!
-rawstr4c .
-```
-
-```bash
-zef uninstall rawstr4c
-```
-
-
-
-
-
-## Debug
-
-```bash
-just rawstr4c --debug
-# Note: there must be an = between option value and option
-just rawstr4c --debug=parser
-just rawstr4c --debug=generator
-```
-
-
-
-
-
-## Test
-
-Run test scripts
-
-```bash
-cd test
-
-raku ./xx-file.rakutest
-```
-
-Test executable file
-
-```bash
-just rawstr4c
-```
-
-
-
-
-
-[rakudo]: https://rakudo.org/
-[just]: https://github.com/casey/just
diff --git a/tool/rawstr4c/lib/Rawstr4c/Config.rakumod b/tool/rawstr4c/lib/Rawstr4c/Config.rakumod
deleted file mode 100644
index e66b3ed..0000000
--- a/tool/rawstr4c/lib/Rawstr4c/Config.rakumod
+++ /dev/null
@@ -1,174 +0,0 @@
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: Artistic-2.0
-# ---------------------------------------------------------------
-# File Name : Config.rakumod
-# File Authors : Aoran Zeng
-# Contributors : Nul None
-# Created On : <2025-07-16>
-# Last Modified : <2025-07-16>
-#
-# Represent a section's working configuration
-# ---------------------------------------------------------------
-
-use Rawstr4c::Parser;
-
-unit module Rawstr4c::Config;
-
-#| 一个 section 的配置 (基于层次化结构而形成的最终真正生效的配置)
-class SectionConfig {
-
- has Rawstr4c::Parser::Section $.section;
-
- method new($section) {
- self.bless(:$section);
- }
-
- #| 从当前 section 开始,向上遍历父节点查找配置项
- #|
- #| @param $default 注意,这里要使用配置项值的语法!
- #|
- method get-inherited-config($key, Str $default?) {
- my $current = $.section;
- while $current {
- if $current.configblock.exist($key) {
-
- return $current.configblock.get($key);
- }
- $current = $current.parent;
- }
- # 如果都没找到,生成一个新值
- # 当 $default 为空时,生成的是 RS4C-Nil
- return Rawstr4c::Parser::ConfigItem's-Value.new($default);
- }
-
-
- #| 非层次化读取,仅读取当前 section 自己的配置项
- #|
- #| @param $default 注意,这里要使用配置项值的语法!
- #|
- method get-direct-config($key, Str $default?) {
-
- if $.section.configblock.exist($key) {
- return $.section.configblock.get($key);
- }
-
- if ! $default.defined {
- # say "DEBUG: Key <$key> is undefined";
- }
- return Rawstr4c::Parser::ConfigItem's-Value.new($default);
- }
-
-
- # ============================================================
-
- # 返回当前 section 的 各种配置
- # 注意,这些函数全部都返回 ConfigValue's-Value 实例
-
- #| RS4C-Mode
- method translate-mode() {
- return self.get-inherited-config('translate', ':escape');
- }
-
- #| RS4C-Mode
- method output-mode() {
- return self.get-inherited-config('output', ':terminal');
- }
-
- #| RS4C-String
- method prefix() {
- return self.get-inherited-config('prefix', '_rawstr4c');
- }
-
- #| RS4C-String
- method postfix() {
- # RS4C-Mode 或 RS4C-String
- my $config-postfix = self.get-inherited-config('postfix', ':use-language');
-
- my $language = self.language.string-value;
- my $postfix;
-
- if $config-postfix.is-mode() && $config-postfix.mode-value() eq 'use-language' {
- $postfix = 'in_' ~ $language;
- } else {
- # 如果不是模式,那就是用户给了一个具体的字符串
- $postfix = $config-postfix.string-value();
- }
-
- return Rawstr4c::Parser::ConfigItem's-Value.new($postfix);
- }
-
- #| RS4C-Bool
- method keep-prefix() {
- return self.get-inherited-config('keep-prefix', 'true');
- }
-
- #| RS4C-Bool
- method keep-postfix() {
- return self.get-inherited-config('keep-postfix', 'true');
- }
-
-
- #| RS4C-String
- method language() {
- # RS4C-String 或 RS4C-Nil
- my $config-language = self.get-direct-config('language');
-
- my Str $lang;
-
- if $config-language.is-nil {
- # codeblock 没有写语言,就给 Unknown
- $lang = 'Unknown';
- } else {
- $lang = $config-language.string-value;
- }
- return Rawstr4c::Parser::ConfigItem's-Value.new($lang);
- }
-
-
- #| RS4C-String
- method name() {
- # RS4C-String 或 RS4C-Nil
- my $config-name = self.get-direct-config('name');
-
- my $name;
-
- if $config-name.is-nil {
- $name = $.section.title.lc
- } else {
- $name = $config-name.string-value;
- }
- return Rawstr4c::Parser::ConfigItem's-Value.new($name);
- }
-
- #| RS4C-Bool
- method name-literally() {
- return self.get-direct-config('name-literally', 'false');
- }
-
-
- # RS4C-String
- method namespace() {
- my $config-namespace = self.get-direct-config('namespace', '');
-
- my $current-namespace = $config-namespace.string-value;
-
- # 嵌套增加
- my $parent = $.section.parent;
- while $parent {
- if $parent.configblock.exist('namespace') {
- $current-namespace = $parent.configblock.get('namespace').string-value ~ $current-namespace;
- } else {
- # 空字符串
- $current-namespace = '' ~ $current-namespace;
- }
- $parent = $parent.parent;
- }
- return Rawstr4c::Parser::ConfigItem's-Value.new($current-namespace);
- }
-
-
- #| RS4C-Bool
- method debug() {
- return self.get-inherited-config('debug', 'false');
- }
-}
diff --git a/tool/rawstr4c/lib/Rawstr4c/Generator.rakumod b/tool/rawstr4c/lib/Rawstr4c/Generator.rakumod
deleted file mode 100644
index e45fe4d..0000000
--- a/tool/rawstr4c/lib/Rawstr4c/Generator.rakumod
+++ /dev/null
@@ -1,291 +0,0 @@
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: Artistic-2.0
-# ---------------------------------------------------------------
-# File Name : Generator.rakumod
-# File Authors : Aoran Zeng
-# Contributors : Nul None
-# Created On : <2025-07-12>
-# Last Modified : <2025-07-16>
-#
-# Generates C code from rawstr4c configuration
-# ---------------------------------------------------------------
-
-unit module Rawstr4c::Generator;
-
-use Rawstr4c::Parser;
-use Rawstr4c::Config;
-use Rawstr4c::Version;
-
-my class CStringConverter {
-
- method convert-char($char, $mode) {
- given $mode {
- when 'oct' {
- my $bytes = $char.encode('UTF-8');
- return $bytes.map({ "\\" ~ sprintf("%03o", $_) }).join('');
- }
- when 'hex' {
- my $bytes = $char.encode('UTF-8');
- return $bytes.map({ "\\x" ~ sprintf("%02x", $_) }).join('');
- }
- when 'escape' {
- given $char {
- when '"' { return '\\"'; }
- when '\\' { return '\\\\'; }
- when "\n" { return '\\n'; }
- when "\t" { return '\\t'; }
- when "\r" { return '\\r'; }
- when "\0" { return '\\0'; }
- default { return $char; }
- }
- }
- default { die "Unknown translate mode: $mode"; }
- }
- }
-
- method convert-string($content, $mode) {
- my $result = "";
- for $content.comb -> $char {
- $result ~= self.convert-char($char, $mode);
- }
- return $result;
- }
-}
-
-
-
-my class CVariableNameGenerator {
-
- method generate($section) {
-
- my $config = Rawstr4c::Config::SectionConfig.new($section);
-
- my $prefix = $config.prefix.string-value;
- my $postfix = $config.postfix.string-value;
-
- my $keep-prefix = $config.keep-prefix.bool-value;
- my $keep-postfix = $config.keep-postfix.bool-value;
-
- my $name = $config.name.string-value;
- my $namespace = $config.namespace.string-value;
- my $name-literally = $config.name-literally.bool-value;
-
- # 替换非法字符
- $name = $name.subst(/<-[a..z A..Z 0..9 _]>/, '_', :g);
- # 合并连续的下划线
- $name = $name.subst(/_+/, '_', :g);
- # 移除结尾的下划线
- $name = $name.subst(/_+$/, '');
-
-
- my $varname = "";
- if $name-literally {
- # 如果是字面量,直接使用原名
- $varname = $name;
- } else {
- # 否则,按照规则组装变量名
- $varname ~= $prefix if $keep-prefix && $prefix;
-
- $varname ~= "_" if $varname && $namespace;
- $varname ~= $namespace if $namespace;
-
- $varname ~= "_" if $varname && $name;
- $varname ~= $name if $name;
-
- $varname ~= "_" if $varname && $postfix && $keep-postfix;
- $varname ~= $postfix if $postfix && $keep-postfix;
- }
- return $varname || "unnamed_var";
- }
-}
-
-
-#| 生成 .h 文件或/和 .c 文件,或存储到 @variables 中
-my class CVariableGenerator {
- has Hash @.variables;
- has Str $.c-header-filename;
-
- method new() {
-
- my $c-header-filename = "rawstr4c.h";
-
- self.bless(:$c-header-filename, :variables([]));
- }
-
- #| C变量名,C变量值, 生成类型
- method add-variable($name, $value, $kind) {
- @.variables.push: {
- name => $name,
- value => $value,
- kind => $kind
- };
- }
-
- #| 生成 C 头文件的内容
- method generate-c-header-file() {
- my $header = qq:to/EOF/;
- #pragma once
-
- /**
- * Generated by rawstr4c v{Version::VERSION}-{Version::RELEASE_DATE}
- *
- * Date: {DateTime.now.Str}
- */
-
- EOF
-
- for @.variables -> $var {
- given $var {
- when 'global-variable-only-header' {
- $header ~= "char {$var}[] = \"{$var}\";\n\n";
- }
- when 'global-variable' {
- $header ~= "extern char {$var}[];\n";
- }
- when 'macro' {
- $header ~= "#define {$var.uc} \"{$var}\"\n\n";
- }
- default {
- die "Unknown variable kind: {$var}";
- }
- }
- }
-
- return $header;
- }
-
- #| 生成 C 源文件的内容
- method generate-c-source-file() {
- my $source = qq:to/EOF/;
- /**
- * Generated by rawstr4c v{Version::VERSION}-{Version::RELEASE_DATE}
- *
- * Date: {DateTime.now.Str}
- */
-
- #include "{$.c-header-filename}"
-
- EOF
-
- for @.variables -> $var {
- if $var eq 'global-variable' {
- $source ~= "char {$var}[] = \"{$var}\";\n";
- }
- }
- return $source;
- }
-
-
- method save-files($dest-dir) {
-
- my $c-header-file = $dest-dir.IO.child($.c-header-filename).Str;
-
- $c-header-file.IO.spurt(self.generate-c-header-file());
- say "Generated C header file: $c-header-file";
-
- # 检查是否有 "头、源并存的变量",如果有就使用并存的头文件和源文件模式
- my $need-gen-c-source-file = @.variables.grep({ $_ eq 'global-variable' }).elems > 0;
-
- if $need-gen-c-source-file {
- my $c-source-filename = $.c-header-filename.subst(/'.h'$/, '.c');
- my $c-source-file = $dest-dir.IO.child($c-source-filename).Str;
- $c-source-file.IO.spurt(self.generate-c-source-file());
- say "Generated C source file: $c-source-file";
- }
- }
-}
-
-
-class Generator {
-
- has Bool $!enable-debug = False; # 是否启用调试模式
- has Rawstr4c::Parser::Parser $.parser;
- has CStringConverter $.string-converter;
- has CVariableNameGenerator $.varname-generator;
- has CVariableGenerator $.variable-generator;
-
- method new($parser) {
- self.bless(
- :$parser,
- :string-converter(CStringConverter.new),
- :varname-generator(CVariableNameGenerator.new),
- :variable-generator(CVariableGenerator.new)
- );
- }
-
- method debug() {
- $!enable-debug = True;
- }
-
- method generate-for-section($section) {
- my $configblock = $section.configblock;
- my $title = $section.title;
- my $rawstr = $section.codeblock;
-
- my $config = Rawstr4c::Config::SectionConfig.new($section);
-
- my $debug-in-config = $config.debug.bool-value;
-
- return unless $rawstr;
-
- my $translate-mode = $config.translate-mode.mode-value;
- my $output-mode = $config.output-mode.mode-value;
- my $varname = $.varname-generator.generate($section);
-
- if $debug-in-config || $!enable-debug {
- my $language = $config.language.string-value;
- my $prefix = $config.prefix.string-value;
- my $postfix = $config.postfix.string-value;
-
- say "------ Section: $title ------";
- say "Output mode = $output-mode";
- say "Translate mode = $translate-mode";
- say "Language = $language";
- say "Prefix = $prefix";
- say "Postfix = $postfix";
- say "Variable name = $varname";
- say '';
- }
-
- my $c-string = $.string-converter.convert-string($rawstr, $translate-mode);
-
- given $output-mode {
- when 'terminal' {
- say 'char ' ~ $varname ~ '[] = "' ~ $c-string ~ '";';
- say "";
- }
- when 'global-variable' {
- $.variable-generator.add-variable($varname, $c-string, 'global-variable');
- }
- when 'global-variable-only-header' {
- $.variable-generator.add-variable($varname, $c-string, 'global-variable-only-header');
- }
- when 'macro' {
- $.variable-generator.add-variable($varname, $c-string, 'macro');
- }
- default {
- die "Illegal output mode: $output-mode";
- }
- }
- }
-
-
- method generate() {
-
- my $root-section = $.parser.root-section;
-
- # 获取所有需要处理的 sections:包括 root section 和所有子 sections
- my @all-sections = ($root-section, |$root-section.get-all-descendants());
-
- # 这个 generate-for-section() 要么把变量输出到终端,要么累计到 @variables 中
- for @all-sections -> $section {
- self.generate-for-section($section);
- }
-
- # 如果有任何变量被添加 (没有被输出到终端),就保存文件
- if $.variable-generator.variables.elems > 0 {
- my $dest-dir = $.parser.input-file.IO.dirname.Str;
- $.variable-generator.save-files($dest-dir);
- }
- }
-}
diff --git a/tool/rawstr4c/lib/Rawstr4c/Parser.rakumod b/tool/rawstr4c/lib/Rawstr4c/Parser.rakumod
deleted file mode 100644
index 8d6a70b..0000000
--- a/tool/rawstr4c/lib/Rawstr4c/Parser.rakumod
+++ /dev/null
@@ -1,356 +0,0 @@
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: Artistic-2.0
-# ---------------------------------------------------------------
-# File Name : Parser.rakumod
-# File Authors : Aoran Zeng
-# Contributors : Nul None
-# Created On : <2025-07-12>
-# Last Modified : <2025-07-16>
-#
-# rawstr4c.md parsing
-# ---------------------------------------------------------------
-
-unit module Rawstr4c::Parser;
-
-#| 不能用 Bool,只能用 Boolean
-my enum ConfigItem's-ValueType < RS4C-Nil RS4C-String RS4C-Mode RS4C-Bool>;
-
-#| 配置项的值
-class ConfigItem's-Value {
- has ConfigItem's-ValueType $.type;
- has Str $.raw-value;
- has Any $.parsed-value;
-
- #| $raw-text 为 undefined 的情况只有一种,那就是内部刻意生成
- method new(Str $input-text) {
- my $type;
- my $parsed-value;
-
- my $raw-value = $input-text;
-
- # 明确区分空字符串和无值情况
- # 这种情况不可能是用户写的(并没有nil这个字面量)
- if ! $input-text.defined {
- $type = RS4C-Nil;
- $parsed-value = Nil;
- $raw-value = ""; # 一个完全用不到的值,但是由于 $.raw-value 类型是字符串,所以必须随便给一个值
- }
- else {
- # wrtd: 不要试图在这里利用 given when 统一处理未定义的值,因为会一直报错
- given $input-text {
- when /^ ':' (.+) $/ {
- # 模式值 :mode
- $type = RS4C-Mode;
- $parsed-value = ~$0;
- }
- when /^ ('true'|'false'|'yes'|'no') $/ {
- # 特殊字面量 - true/false/yes/no 都是 literal
- $type = RS4C-Bool;
- $parsed-value = ~$0 ~~ /^('true'|'yes')$/ ?? True !! False;
- }
- # 输入为空时被当做是字符串类型
- default {
- # 普通字符串
- $type = RS4C-String;
- $parsed-value = $input-text;
- }
- }
- }
- self.bless(:$type, :$raw-value, :$parsed-value);
- }
-
- # 获得适合调用者接受的值
- method value() {
- given $.type {
- when RS4C-Nil | RS4C-String | RS4C-Bool | RS4C-Mode { return $.parsed-value; }
- default { die "Unknown config value type: {$.type}"; }
- }
- }
-
- # 这些函数防止开发者写错类型
- method nil-value() {
- return self.value if $.type == RS4C-Nil;
- die "The config value type should be RS4C-Nil, but it is: {$.type}";
- }
-
- method string-value() {
- return self.value if $.type == RS4C-String;
- die "The config value type should be RS4C-String, but it is: {$.type}";
- }
-
- method bool-value() {
- return self.value if $.type == RS4C-Bool;
- die "The config value type should be RS4C-Bool, but it is: {$.type}";
- }
-
- method mode-value() {
- return self.value if $.type == RS4C-Mode;
- die "The config value type should be RS4C-Mode, but it is: {$.type}";
- }
-
-
- # 类型检查方法
- method is-nil() { return $.type == RS4C-Nil; }
- method is-mode() { return $.type == RS4C-Mode; }
- method is-bool() { return $.type == RS4C-Bool; }
- method is-string() { return $.type == RS4C-String; }
-}
-
-
-
-#| 包含所有 config items 的容器
-#| 所有 get 出的值一定是 ConfigItem's-Value 实例
-my class ConfigBlock {
-
- has %!items;
-
- # 如果非要在程序内部中调用,而不是直接从 Markdown 文件中读取出来
- # 一定要记得 $raw-value 用的是 rawstr4c 的语法!也就是说,这里一定是一个字符串
- method set($k, $raw-value) {
- %!items{$k} = ConfigItem's-Value.new($raw-value);
- }
-
- method get($k) {
- return %!items{$k};
- }
-
- method exist($k) {
- return %!items{$k}:exists;
- }
-
- # 配置项名称
- # @danger: 把这个函数命名为 items,会让我的机器蓝屏.....
- method keys() {
- return %!items.keys;
- }
-}
-
-
-#| 表示一个 section
-class Section {
-
- has Str $.title;
- has Int $.level;
- has ConfigBlock $.configblock;
- has Str $.codeblock is rw;
- has Section $.parent is rw;
- has Section @.children;
-
-
- method new($title, $level) {
- my $configblock = ConfigBlock.new();
- # parent 和 codeblock 刻意不初始化
- self.bless(:$title, :$level, :$configblock, :children([]));
- }
-
- method add-child($child-section) {
- $child-section.parent = self;
- @.children.push: $child-section;
- }
-
- method has-children() {
- return @.children.elems > 0;
- }
-
- # 递归获取所有后代section(深度优先遍历)
- method get-all-descendants() {
- my @descendants;
- for @.children -> $child {
- @descendants.push: $child;
- @descendants.append: $child.get-all-descendants();
- }
- return @descendants;
- }
-
- # 获取section的路径(从根到当前节点)
- method get-hierarchical-path() {
- my @path;
- my $current = self;
- while $current {
- @path.unshift: $current.title;
- $current = $current.parent;
- }
- return @path.join(" > ");
- }
-}
-
-
-#|(
-所有内容都是 section:
-
- - level 0: root section 无标题
- - level 1: # 一级标题
- - level 2: ## 二级标题
- - ...
-)
-class Parser {
- has Str $.input-file is rw;
- #| 所有sections的扁平数组,已经是深度遍历的了
- has Section @!sections;
-
- #| $markdown-file 必须是一个存在的 markdown 文件路径
- method new($markdown-file) {
- self.bless(:input-file($markdown-file));
- }
-
- # 获取根section(level 0)
- method root-section() {
- return @!sections.first({ $_.level == 0 });
- }
-
- # 配置项所在行 -> 解析为配置项
- method parse-config-item-line($line, $section-config) {
- # 语法: - key = `value`
- if $line ~~ /^ '-' \s* (<[a..z\-]>+) \s* '=' \s* '`' (.+?) '`' / {
- my $key = ~$0;
- my $value = ~$1;
- $section-config.set($key, $value);
- return True;
- }
- return False;
- }
-
-
- method parse() {
- my $content = $.input-file.IO.slurp;
- my @lines = $content.lines;
-
- my $current-section;
- my $in-codeblock = False;
-
- # 在代码块中的 raw string
- my $rawstr = "";
-
- # 无论有没有具体的 root 信息 (比如所处理的文件第一行就是标题),
- # 都创建一个 root section (level 0)
- $current-section = Section.new("", 0);
- @!sections.push: $current-section;
-
- # 开始遍历
- my $line-count = 0;
- for @lines -> $line {
- $line-count++;
-
- # Step1: 处理标题,这里最重要,因为是判断上一个 section 结束的标志
- if !$in-codeblock && $line ~~ /^ '#' ('#'*) \s* (.+) / {
- my $level = 1 + $0.chars;
- my $title = ~$1;
-
- # 保存当前section的codeblock
- $current-section.codeblock = $rawstr;
-
- # 准备创建一个新的 section
- $rawstr = "";
- my $new-section = Section.new($title, $level);
- @!sections.push: $new-section;
-
- # 找到合适的父节点
- my $parent = self.find-parent-section($level);
-
- if $parent {
- $parent.add-child($new-section);
- }
-
- $current-section = $new-section;
- next;
- }
-
- # Step2: 处理配置项 (如果该行不是配置项则下一行)
- if self.parse-config-item-line($line, $current-section.configblock) {
- next;
- }
-
- # Step3: 开始处理 codeblock
- if $line ~~ /^ '```' (.*)? / {
- if $in-codeblock {
- $in-codeblock = False;
- } else {
- $in-codeblock = True;
- my $lang = ~($0 // '');
- if $lang && $current-section && !$current-section.configblock.exist('language') {
- $current-section.configblock.set('language', $lang);
- }
- }
- next;
- }
-
- # 代码块里的内容统统进来
- if $in-codeblock {
- $rawstr ~= $line ~ "\n";
- }
- }
-
- # 遍历结束,保存最后一个section的codeblock
- if $rawstr && $current-section {
- $current-section.codeblock = $rawstr;
- }
- }
-
- method find-parent-section($new-level) {
- # 从@!sections尾部向前找,找到第一个level小于new-level的section作为父节点
- for @!sections.reverse -> $section {
- if $section.level < $new-level {
- return $section;
- }
- }
- return Nil; # 没有找到父节点,说明是 root section
- }
-
-
-
- # 调试方法:扁平打印所有sections
- method debug-print-sections-flatly() {
- say "====== Sections ======";
- for @!sections.kv -> $i, $section {
- my $title = $section.title || "(Root)";
- my $has-config = $section.configblock.keys ?? "[Has Config]" !! "[NO Config]";
- my $has-code = $section.codeblock ?? "[Has Code]" !! "[NO Code]";
- say " [$i] Level {$section.level}: $title - $has-config, $has-code";
- }
- }
-
- # 调试方法:层级打印sections
- method debug-print-sections-hierarchyly() {
- say "====== Hierarchy ======";
-
- my $indent = 0;
-
- # 嵌套的格式化函数
- my sub format-section($section, $level) {
- my $prefix = ' ' x $level;
- my $title = $section.title // '(Root)';
- my $base-info = "{$prefix}- {$title} (level {$section.level})";
-
- my $config-info = "";
- if $section.configblock.keys {
- my @config-items;
- for $section.configblock.keys -> $key {
- my $value = $section.configblock.get($key);
- @config-items.push: "$key = {$value.raw-value}";
- }
- $config-info = "\n" ~ "{$prefix} [" ~ @config-items.join(", ") ~ "]";
- }
- return $base-info ~ $config-info;
- }
-
- # 嵌套的递归打印函数
- my sub print-section-tree($section, $level) {
- say format-section($section, $level);
-
- if $section.has-children {
- for $section.children -> $child {
- print-section-tree($child, $level + 1);
- }
- }
- }
-
- my $root = self.root-section();
- print-section-tree($root, $indent);
- }
-
- # 调试方法:完整的调试信息打印
- method debug() {
- self.debug-print-sections-flatly();
- self.debug-print-sections-hierarchyly();
- }
-}
diff --git a/tool/rawstr4c/lib/Rawstr4c/Version.rakumod b/tool/rawstr4c/lib/Rawstr4c/Version.rakumod
deleted file mode 100644
index 0bc3f72..0000000
--- a/tool/rawstr4c/lib/Rawstr4c/Version.rakumod
+++ /dev/null
@@ -1,27 +0,0 @@
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: Artistic-2.0
-# ---------------------------------------------------------------
-# File Name : Version.rakumod
-# File Authors : Aoran Zeng
-# Contributors : Nul None
-# Created On : <2025-07-14>
-# Last Modified : <2025-07-16>
-# ---------------------------------------------------------------
-
-unit module Rawstr4c::Version;
-
-constant VERSION = "0.2.1.0";
-constant RELEASE_DATE = "2025/07/16";
-
-constant Maintain_URL = "https://github.com/RubyMetric/chsrc/blob/dev/tool/rawstr4c";
-constant Maintain_URL2 = "https://gitee.com/RubyMetric/chsrc/blob/dev/tool/rawstr4c";
-
-constant VERSION_CONTENT_FOR_-version = qq:to/EOF/
- rawstr4c {VERSION}
- Copyright (C) 2025 Aoran Zeng
- License Artistic-2.0: Artistic License 2.0
- This is free software: you are free to change and redistribute it.
- There is NO WARRANTY, to the extent permitted by law.
-
- Written by Aoran Zeng.
- EOF
diff --git a/tool/rawstr4c/make-distribution.ps1 b/tool/rawstr4c/make-distribution.ps1
deleted file mode 100644
index cb7e771..0000000
--- a/tool/rawstr4c/make-distribution.ps1
+++ /dev/null
@@ -1,63 +0,0 @@
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: GPL-3.0-or-later
-# ---------------------------------------------------------------
-# Script Name : make-distribution.ps1
-# Script Authors : Aoran Zeng
-# Created On : <2025-07-21>
-# Last Modified : <2025-07-21>
-#
-# Make rawstr4c distribution file (tar.gz)
-#
-# Usage:
-#
-# .\make-distribution.ps1 [-upload]
-# ---------------------------------------------------------------
-
-param(
- [switch]$upload
-)
-
-$files = @()
-
-# 获取相对路径的函数
-function Get-RelativePath($item) {
- # K:\chsrc\tool\rawstr4c
- # K:\chsrc\tool\rawstr4c\our-dist-file
- # 注意我们必须要删掉这里的\,这就是 +1 的原因
- return $item.FullName.Substring((Get-Location).Path.Length + 1)
-}
-
-# 添加 lib 目录(排除 .precomp)
-$files += Get-ChildItem lib -Recurse | Where-Object { $_.FullName -notlike "*\.precomp*" } | ForEach-Object { Get-RelativePath $_ }
-
-# 添加其他目录
-$files += Get-ChildItem bin, doc, test -Recurse | ForEach-Object { Get-RelativePath $_ }
-
-# 添加根目录文件
-$rootFiles = @('META6.json', 'LICENSE', 'README.md')
-foreach ($file in $rootFiles) {
- if (Test-Path $file) {
- $files += $file
- }
-}
-
-# 打包
-$archiveName = "rawstr4c-$(Get-Date -Format 'yyyyMMdd').tar.gz"
-$files | tar -czf $archiveName -T -
-
-Write-Host "打包完成: $archiveName" -ForegroundColor Green
-Write-Host "提示: 可指定 -upload 直接上传" -ForegroundColor Green
-
-# 如果指定了 upload 参数,则上传到 fez
-if ($upload) {
- Write-Host "正在上传到 fez..." -ForegroundColor Yellow
-
- try {
- fez upload --file $archiveName
- Write-Host "上传成功!" -ForegroundColor Green
- } catch {
- Write-Error "上传失败: $_"
- exit 1
- }
-}
-
diff --git a/tool/rawstr4c/run/run.bat b/tool/rawstr4c/run/run.bat
deleted file mode 100644
index 5658761..0000000
--- a/tool/rawstr4c/run/run.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-:: ---------------------------------------------------------------
-:: SPDX-License-Identifier: GPL-3.0-or-later
-:: ---------------------------------------------------------------
-:: File Name : run.bat
-:: File Authors : Aoran Zeng
-:: Contributors : Nul None
-:: Created On : <2025-07-13>
-:: Last Modified : <2025-07-21>
-::
-:: Run rawstr4c
-::
-:: Usage:
-::
-:: 用户必须在代码根目录中运行此文件
-::
-:: %PREFIX%\run\run.bat [--debug]
-::
-:: %PREFIX%\run\run.bat [--debug]
-:: ---------------------------------------------------------------
-
-@echo off
-set PREFIX=tool\rawstr4c
-REM -I 选项必须在文件前面
-raku -I %PREFIX%\lib %PREFIX%\bin\rawstr4c %*
diff --git a/tool/rawstr4c/run/run.ps1 b/tool/rawstr4c/run/run.ps1
deleted file mode 100644
index dc9bfc1..0000000
--- a/tool/rawstr4c/run/run.ps1
+++ /dev/null
@@ -1,24 +0,0 @@
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: GPL-3.0-or-later
-# ---------------------------------------------------------------
-# File Name : run.ps1
-# File Authors : Aoran Zeng
-# Contributors : Nul None
-# Created On : <2025-07-12>
-# Last Modified : <2025-07-21>
-#
-# Run rawstr4c
-#
-# Usage:
-#
-# 用户必须在代码根目录中运行此文件
-#
-# $PREFIX\run\run.ps1 [--debug]
-#
-# $PREFIX\run\run.ps1 [--debug]
-# ---------------------------------------------------------------
-
-$PREFIX = "tool/rawstr4c"
-
-# -I 选项必须在文件前面
-raku -I $PREFIX\lib $PREFIX\bin\rawstr4c $args
diff --git a/tool/rawstr4c/run/run.sh b/tool/rawstr4c/run/run.sh
deleted file mode 100644
index 830bd31..0000000
--- a/tool/rawstr4c/run/run.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env bash
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: GPL-3.0-or-later
-# ---------------------------------------------------------------
-# File Name : run.sh
-# File Authors : Aoran Zeng
-# Contributors : Nul None
-# Created On : <2025-07-13>
-# Last Modified : <2025-07-21>
-#
-# Run rawstr4c
-#
-# Usage:
-#
-# 用户必须在代码根目录中运行此文件!
-#
-# $PREFIX/run/run.sh [--debug]
-#
-# $PREFIX/run/run.sh [--debug]
-# ---------------------------------------------------------------
-
-PREFIX="tool/rawstr4c"
-
-# -I 选项必须在文件前面
-raku -I $PREFIX/lib $PREFIX/bin/rawstr4c "$@"
diff --git a/tool/rawstr4c/test/00-success.rakutest b/tool/rawstr4c/test/00-success.rakutest
deleted file mode 100644
index d828c02..0000000
--- a/tool/rawstr4c/test/00-success.rakutest
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env raku
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: GPL-3.0-or-later
-# ---------------------------------------------------------------
-# Test File : 00-success.rakutest
-# Test Authors : Aoran Zeng
-# Created On : <2025-07-21>
-# Last Modified : <2025-07-21>
-#
-# $(cwd) 为 test/ 时:
-#
-# raku ./00-success.rakutest
-# ---------------------------------------------------------------
-
-use Test;
-
-pass;
-
-# 最后总结
-done-testing;
diff --git a/tool/rawstr4c/test/01-distribution.rakutest b/tool/rawstr4c/test/01-distribution.rakutest
deleted file mode 100644
index 0093809..0000000
--- a/tool/rawstr4c/test/01-distribution.rakutest
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env raku
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: GPL-3.0-or-later
-# ---------------------------------------------------------------
-# Test File : 01-distribution.rakutest
-# Test Authors : Aoran Zeng
-# Created On : <2025-07-21>
-# Last Modified : <2025-07-21>
-#
-# $(cwd) 为 test/ 时:
-#
-# raku ./01-distribution.rakutest
-# ---------------------------------------------------------------
-
-use lib '../lib';
-use Test;
-use Test::META;
-
-use-ok 'Rawstr4c::Parser';
-use-ok 'Rawstr4c::Config';
-use-ok 'Rawstr4c::Generator';
-use-ok 'Rawstr4c::Version';
-
-# 检查 META6.json
-meta-ok;
-
-done-testing;
diff --git a/tool/rawstr4c/test/10-parser.rakutest b/tool/rawstr4c/test/10-parser.rakutest
deleted file mode 100644
index b0b600d..0000000
--- a/tool/rawstr4c/test/10-parser.rakutest
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env raku
-# ---------------------------------------------------------------
-# SPDX-License-Identifier: GPL-3.0-or-later
-# ---------------------------------------------------------------
-# Test File : 10-parser.rakutest
-# Test Authors : Aoran Zeng
-# Created On : <2025-07-15>
-# Last Modified : <2025-07-21>
-#
-# $(cwd) 为 test/ 时:
-#
-# raku ./10-parser.rakutest
-# ---------------------------------------------------------------
-
-use lib '../lib';
-use Rawstr4c::Parser;
-
-my $test-file1 = './fixture/hierarchy-with-root.md';
-my $test-file2 = './fixture/hierarchy-without-root.md';
-my $parser1 = Rawstr4c::Parser::Parser.new($test-file1);
-my $parser2 = Rawstr4c::Parser::Parser.new($test-file2);
-
-$parser1.parse();
-$parser2.parse();
-
-# 测试两个文件
-$parser1.debug();
-say "";
-$parser2.debug();
diff --git a/tool/rawstr4c/test/fixture/hierarchy-with-root.md b/tool/rawstr4c/test/fixture/hierarchy-with-root.md
deleted file mode 100644
index 9008026..0000000
--- a/tool/rawstr4c/test/fixture/hierarchy-with-root.md
+++ /dev/null
@@ -1,74 +0,0 @@
-- root-prefix = `GLOBAL_`
-- root-output = `:terminal`
-
-```c
-int root_code_block = 1;
-```
-
-some comments
-
-
-
-# Java
-
-- java-prefix = `JAVA_`
-
-## Maven Config
-
-- maven-name = `maven`
-
-```xml
-
-
-
-
-```
-
-## Gradle Config
-
-```groovy
-repositories {
- maven { url 'https://example.com' }
-}
-```
-
-
-
-# Python
-
-- python-prefix = `PYTHON_`
-
-## pip config
-
-```bash
-pip config set global.index-url https://example.com
-```
-
-## conda config
-
-- language = `yaml`
-
-```
-channels:
- - https://example.com/conda
-```
-
-
-
-# Docker
-
-## Dockerfile
-
-```dockerfile
-FROM ubuntu:20.04
-RUN echo "Hello World"
-```
-
-### Multi-stage Build
-
-```dockerfile
-FROM node:16 AS builder
-WORKDIR /app
-COPY . .
-RUN npm install
-```
diff --git a/tool/rawstr4c/test/fixture/hierarchy-without-root.md b/tool/rawstr4c/test/fixture/hierarchy-without-root.md
deleted file mode 100644
index 153bffc..0000000
--- a/tool/rawstr4c/test/fixture/hierarchy-without-root.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Java
-
-- java-prefix = `JAVA_`
-
-## Maven Config
-
-- maven-name = `maven`
-
-```xml
-
-
-
-
-```
-
-## Gradle Config
-
-```groovy
-repositories {
- maven { url 'https://example.com' }
-}
-```
-
-
-
-# Python
-
-- python-prefix = `PYTHON_`
-
-## pip config
-
-```bash
-pip config set global.index-url https://example.com
-```
-
-## conda config
-
-- language = `yaml`
-
-```
-channels:
- - https://example.com/conda
-```
-
-
-
-# Docker
-
-## Dockerfile
-
-```dockerfile
-FROM ubuntu:20.04
-RUN echo "Hello World"
-```
-
-### Multi-stage Build
-
-```dockerfile
-FROM node:16 AS builder
-WORKDIR /app
-COPY . .
-RUN npm install
-```
diff --git a/tool/rawstr4c/test/fixture/inherited-config.md b/tool/rawstr4c/test/fixture/inherited-config.md
deleted file mode 100644
index 91db146..0000000
--- a/tool/rawstr4c/test/fixture/inherited-config.md
+++ /dev/null
@@ -1,28 +0,0 @@
-- prefix = `ROOT`
-- keep-prefix = `true`
-
-```c
-root code;
-```
-
-# Level 1
-
-- prefix = `L1`
-
-```c
-level1 code;
-```
-
-## Level 2
-
-```c
-level2 code;
-```
-
-### Level 3
-
-- prefix = `L3`
-
-```c
-level3 code;
-```
diff --git a/tool/rawstr4c/test/fixture/output-to-terminal-besides-save-files.md b/tool/rawstr4c/test/fixture/output-to-terminal-besides-save-files.md
deleted file mode 100644
index 7aa62f3..0000000
--- a/tool/rawstr4c/test/fixture/output-to-terminal-besides-save-files.md
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-# some config
-
-- output = `:terminal`
-
-```toml
-[setting]
-init = true
-```
-
-
-# some code
-
-- output = `:global-variable`
-
-```ruby
-puts 123;
-```
diff --git a/tool/rawstr4c/test/fixture/rawstr4c.md b/tool/rawstr4c/test/fixture/rawstr4c.md
deleted file mode 100644
index f411cd6..0000000
--- a/tool/rawstr4c/test/fixture/rawstr4c.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Test default file name
-
-random words
-
-- name = `test`
-
-rawstr4c config description
-
-```raku
-say "hello world";
-```
-
-code block description
diff --git a/tool/rawstr4c/test/fixture/translate-escape.md b/tool/rawstr4c/test/fixture/translate-escape.md
deleted file mode 100644
index 1a7a434..0000000
--- a/tool/rawstr4c/test/fixture/translate-escape.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Test for escape mode
-
-- translate = `:escape`
-- output = `:terminal`
-
-```bash
-echo "Hello World!"
-printf "Line with \"quotes\" and 'apostrophes'\n"
-```
diff --git a/tool/rawstr4c/test/fixture/translate-hex.md b/tool/rawstr4c/test/fixture/translate-hex.md
deleted file mode 100644
index 0d515b1..0000000
--- a/tool/rawstr4c/test/fixture/translate-hex.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Test for hex mode
-
-- translate = `:hex`
-
-```bash
-echo "Hello World!"
-```
diff --git a/tool/rawstr4c/test/fixture/translate-oct.md b/tool/rawstr4c/test/fixture/translate-oct.md
deleted file mode 100644
index cb510c9..0000000
--- a/tool/rawstr4c/test/fixture/translate-oct.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Test for oct mode
-
-- translate = `:oct`
-
-```bash
-echo "Hello World!"
-```