Template Blocks

Templates are the primary output mechanism in TLang. Each template declares a keyword, a list of target formats, a name, and typed parameters. Calling a template produces a value that Generator.generate() converts to a string.

The Six Template Types

lang — generates source code in any target language: Kotlin, Java, TypeScript, Go, Rust, HTML, YAML, and so on. Requires a generator import. data — generates hierarchical data: HTML, JSON, YAML, XML, TOML. No generator import needed. doc — generates Markdown or HTML documents with semantic structure. No generator import needed. style — generates CSS, SCSS, LESS, JSON design tokens, or JS/TS style objects. No generator import needed. cmd — generates commands: SQL statements, shell scripts, or any named invocation. No generator import needed. raw — embeds verbatim text. AsIs writes it completely untouched; Replaced substitutes $${param} patterns only.

Choosing a Template Type

Use lang when generating source code — Kotlin, Java, TypeScript, Rust, Go, Python, SQL DDL embedded in code, and so on. This type understands code structure: classes, methods, fields, control flow. Use data when generating structured data files — HTML pages, JSON configs, YAML manifests, XML descriptors, TOML files. The output has hierarchical tag/key structure. Use doc when generating human-readable documents with standard sections, headings, code examples, and lists. Works in Markdown and HTML output. Use style when generating presentation: CSS rules, SCSS variables, design tokens in JSON or JS. Use cmd when the output is a command invocation: a SQL query, a bash script, an HTTP request. The cmd type models named calls with typed arguments. Use raw when none of the above fit — Dockerfiles, .gitignore files, shell scripts with complex syntax, or any content that conflicts with TLang keyword parsing.

Template Call Syntax

Call a template like a function. For multi-format templates the first argument selects the format.

      // Single format
      let leaf = entity("com.example", "User")

      // Multi-format — first arg selects format
      let md   = readme("md",   "MyLib")
      let html = readme("html", "MyLib")

      // Then generate the string
      let code  = Generator.generate(leaf)
      let mdStr = Generator.generate(md)
    

Generator.generate()

Generator.generate(templateCall) converts a template instance into a string. For lang templates it dispatches to the appropriate code generator. For doc, data, style, and cmd templates it uses the built-in renderer for the selected format.

      use TLang.Generator
      use KotlinGen as kotlin

      lang [kotlin] entity(pkg: String, cls: String) {
          pkg $${pkg}
          impl[data class] $${cls} { }
      }

      func main(): String {
          let leaf = entity("com.example", "User")
          let code = Generator.generate(leaf)   // → Kotlin source string
          return code
      }
    

Inline Includes

Inside template bodies, the include syntax splices another template's output at that position. This is the primary composition mechanism.

      lang [kotlin] field(decl: String) spec {
          var $${decl}
      }

      lang [kotlin] dataClass(cls: String, fields: List) {
          impl[data class] $${cls} {
              <[ renderFields(fields) ]>
          }
      }

      func renderFields(fields: List): List {
          let nodes = List.create()
          for (f in fields) {
              let nodes = List.push(nodes, field(f))
          }
          return nodes
      }
    

The spec modifier on field marks it as a fragment — it produces inner content without a file wrapper.

Multi-Format Templates

Declare multiple target formats in the brackets. The caller selects by passing the format name as the first argument.

      doc [md, html] readme(project: String) {
        # $${project}

        Welcome to $${project}.
      }

      func main(): String {
          let md   = Generator.generate(readme("md",   "MyLib"))
          let html = Generator.generate(readme("html", "MyLib"))
          File.write("README.md",       md,   true)
          File.write("output/README.html", html, true)
          return "done"
      }