ArtificialNecessity.YeetCode.CLI 0.260706.135048

Prefix Reserved
dotnet tool install --global ArtificialNecessity.YeetCode.CLI --version 0.260706.135048
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local ArtificialNecessity.YeetCode.CLI --version 0.260706.135048
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=ArtificialNecessity.YeetCode.CLI&version=0.260706.135048
                    
nuke :add-package ArtificialNecessity.YeetCode.CLI --version 0.260706.135048
                    

ArtificialNecessity.YeetCode

(C)opyright 2026 by David Jeske davidj@gmail.com Licensed under Apache 2.0

Yeets one language into another. Schema-driven meta-programming for language-to-language transformation.

YeetCode parses any custom syntax into validated HJSON intermediate data, then generates multi-file output through templates with configurable delimiters. Available as both a CLI tool and an MSBuild task.

Installation

NuGet Package (MSBuild Task)

<PackageReference Include="ArtificialNecessity.YeetCode.MSBuild" Version="0.1.*" PrivateAssets="all" />

CLI Tool

dotnet tool install -g ArtificialNecessity.YeetCode

VSCode Extension

Syntax highlighting for all YeetCode file formats (HJSON, YTSON, YTGMR, YTMPL) is available as a VSCode extension. See the VSCode Extension README for details and screenshots.


Two Ways to Use YeetCode

Half Yeet — Data + Template → Output

The simplest mode. You already have your data in HJSON format. YeetCode just runs it through a template to produce output. No grammar, no parsing.

data.hjson → template.ytmpl → output files

When to use: Hand-written data, config files, lookup tables, or data exported from another tool.

Full Yeet — Grammar + Input → Data → Template → Output

The full pipeline. YeetCode parses your custom syntax using a PEG grammar, validates the parsed data against a schema, then runs it through a template.

grammar.ytgmr + input.proto → data.hjson → template.ytmpl → output files
                                    ↑
                            schema.ytschema.ytson
                            (validates + fills defaults)

When to use: Parsing existing file formats (protobuf, IDL, config languages) into generated code.


File Naming Convention

Role Extension Example
Grammar .ytgmr proto.ytgmr
Schema .ytschema.ytson proto.ytschema.ytson
Template .ytmpl proto-csharp.ytmpl
Data .ytdata.hjson widgets.ytdata.hjson
Input .ytinput.ext widgets.ytinput.proto

The last extension always indicates the file format. The yt prefix identifies YeetCode-specific files. User input files keep their own format extension.


CLI Usage

Half Yeet (template command)

yeetcode template \
  --data greeting.ytdata.hjson \
  --template greeting.ytmpl \
  --output greeting.txt

Full Yeet (generate command)

yeetcode generate \
  --schema proto.ytschema.ytson \
  --grammar proto.ytgmr \
  --input widgets.ytinput.proto \
  --template proto-csharp.ytmpl \
  --outdir ./generated/

Other Commands

# Parse only — produce validated HJSON from input
yeetcode parse --schema s.ytson --grammar g.ytgmr --input i.proto --output parsed.hjson

# Validate — check HJSON data against schema
yeetcode validate --schema s.ytson --data d.hjson

MSBuild Task Usage

Add the package reference, then use the tasks in your .csproj:

Half Yeet (YeetCodeTemplateTask)

<Target Name="GenerateFromData" BeforeTargets="CoreCompile">
  <YeetCodeTemplateTask
    DataFile="greeting.ytdata.hjson"
    TemplateFile="greeting.ytmpl"
    OutputFile="generated\greeting.txt" />
</Target>

Full Yeet (YeetCodeGenerateTask)

<Target Name="GenerateFromProto" BeforeTargets="CoreCompile">
  <YeetCodeGenerateTask
    SchemaFile="proto.ytschema.ytson"
    GrammarFile="proto.ytgmr"
    InputFile="widgets.ytinput.proto"
    TemplateFile="proto-csharp.ytmpl"
    OutputDirectory="generated\" />
</Target>

Task Properties

YeetCodeGenerateTask (full yeet):

Property Required Description
SchemaFile ✅ Schema file (.ytschema.ytson)
GrammarFile ✅ Grammar file (.ytgmr)
InputFile ✅ Input file to parse
TemplateFile ✅ Template file (.ytmpl)
FunctionsFile Lookup tables (.hjson)
OutputFile Single-file output path
OutputDirectory Multi-file output directory
Defines Semicolon-separated grammar parameters
LineEndings Output line endings: lf (default), crlf, preserve

YeetCodeTemplateTask (half yeet):

Property Required Description
DataFile ✅ HJSON data file
TemplateFile ✅ Template file (.ytmpl)
SchemaFile Optional schema for validation
FunctionsFile Lookup tables (.hjson)
OutputFile Single-file output path
OutputDirectory Multi-file output directory
LineEndings Output line endings: lf (default), crlf, preserve

Line Endings

By default, all generated output is normalized to LF (\n) line endings, even on Windows, so generated files are byte-identical across platforms. Set LineEndings="crlf" to force CRLF, or LineEndings="preserve" to keep whatever line endings the templates/inputs produce. The CLI equivalent is --line-endings lf|crlf|preserve.


Example: Half Yeet — Greeting Generator

Data (greeting.ytdata.hjson)

{
  greeting: Hello
  name: World
  items: [
    { label: Alpha, value: 1 }
    { label: Beta, value: 2 }
    { label: Gamma, value: 3 }
  ]
}

Template (greeting.ytmpl)

<?yt delim="<% %>" ?>
// Auto-generated — do not edit
<%greeting%>, <%name%>!

Items:
<%each items as item%>
  - <%item.label%> = <%item.value%>
<%/each%>

Output

// Auto-generated — do not edit
Hello, World!

Items:
  - Alpha = 1
  - Beta = 2
  - Gamma = 3

Run it

yeetcode template --data greeting.ytdata.hjson --template greeting.ytmpl

Example: Full Yeet — Proto to C#

Schema (simple.ytschema.ytson)

Defines the shape of the intermediate data:

{
  syntax: string
  package: string
  messages: [{
    name: string
    fields: [{
      name: string
      type: string
      tag: int
    }]
  }]
}

Grammar (simple.ytgmr)

PEG grammar that parses .proto files into the schema shape:

file ::= syntax_decl? package_decl? message*

syntax_decl ::= "syntax" "=" syntax:QUOTED_STRING ";"
package_decl ::= "package" package:IDENT ";"
message ::= "message" name:IDENT "{" fields:field* "}"
field ::= type:IDENT name:IDENT "=" tag:INT ";"

IDENT ::= /[a-zA-Z_][a-zA-Z0-9_.]+/
INT ::= /0|[1-9][0-9]*/
QUOTED_STRING ::= /"[^"]*"/

%skip ::= /(?:\s|\/\/[^\n]*)*/

Input (simple.ytinput.proto)

syntax = "proto3";
package acme.widgets;

message Widget {
  string name = 1;
  int32 quantity = 2;
  string description = 3;
}

Template (simple.ytmpl)

<?yt delim="<% %>" ?>
// Auto-generated from <%syntax%> — do not edit
// Package: <%package%>

<%each messages as msg%>
public class <%msg.name%>
{
    <%each msg.fields as f%>
    public <%f.type%> <%f.name%> { get; set; } // tag <%f.tag%>
    <%/each%>
}
<%/each%>

Output

// Auto-generated from "proto3" — do not edit
// Package: acme.widgets

public class Widget
{
    public string name { get; set; } // tag 1
    public int32 quantity { get; set; } // tag 2
    public string description { get; set; } // tag 3
}

Run it

yeetcode generate \
  --schema simple.ytschema.ytson \
  --grammar simple.ytgmr \
  --input simple.ytinput.proto \
  --template simple.ytmpl

Template Syntax

Templates use configurable delimiters declared in the header:

<?yt delim="<% %>" ?>

Header Options

Option Default Description
delim="OPEN CLOSE" — Required. Delimiter pair for template blocks
trimlines=false true Disable standalone directive line trimming (see below)

Example with trimlines disabled:

<?yt delim="<% %>" trimlines=false ?>

Comments

Use # inside a delimited block to write a comment that produces no output:

<% # This is a YeetCode template comment — it won't appear in output %>

When a comment is the only thing on a line, the entire line (including its newline) is removed from output, so comments don't leave blank lines.

Standalone Directive Line Trimming

By default, when a control directive (each, if, else, /each, /if, define, call, output, # comment, etc.) is the only thing on a line (besides whitespace), the entire line including its newline is removed from output. This prevents blank lines from control-flow directives.

With trimming (default):

<?yt delim="<% %>" ?>
Header
<% each items as item %>
- <% item.name %>
<% /each %>
Footer

Output: Header\n- alpha\n- beta\nFooter\n — no blank lines from each//each.

Without trimming:

<?yt delim="<% %>" trimlines=false ?>

Output preserves the blank lines where directives were.

Value expressions like <% name %> are never trimmed — only control directives.

Directives

Directive Purpose
# comment text Comment (no output)
each collection as item Iterate array
each map as key, value Iterate map key-value pairs
if condition Conditional
elif condition Else-if
else Else
define name(args) Define reusable macro
call name(args) Invoke macro
output filename Multi-file output
/each, /if, /define, /output Close blocks

Built-in Functions

pascal, camel, snake, upper, lower, pascal_dotted, length

Special Variables (inside each)

index (0-based), first (boolean), last (boolean)


Community

Questions, ideas, or feedback? Join the discussion: https://github.com/ArtificialNecessity/AN_YeetCode/discussions

License

Apache 2.0 -- https://github.com/ArtificialNecessity/AN_YeetCode

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.260706.135048 131 7/6/2026