Skip to content

Alternative markup syntax proposal. #2502

Description

@kekekeks

Since the very first thing XamlIl does is conversion of XML to its own AST, we can now create other markup languages relatively cheaply by simply writing a parser that produces the same AST.

Since some people seem to hate XML, here is a non-XML markup proposal:

// Default namespaces for Avalonia, x: and d: are omitted here and added automatically
using local = clr MyNamespace
using lib = xml http://some.lib/xml/namespace
Window 
{
     StackPanel
     {
          // Equivalent of <Button>
          Button
          // Unless followed by = before the end of line, in this case it's a property assignment
          Orientation = "Horizontal"
          Attached.Property="Value"
          // This is an equivalent of <Button Background="Red">Click me</Button>
          Button
          {
               "Click me"
               Background = "Red"
          }
          local:MyControl
          lib:LibraryControl
          clr:System.Collections.Generic.List<clr:System.Int32> {
                1
                2
                3 4 5 6
          }
          // Markup extensions are prefixed by $
          TextBlock { Text = ${Binding SomeVmProp} }
          // $-prefixed strings are a shortcut to {Binding ...}
          TextBlock { x:Name = "Name" Text = $"SomeVmProp" }
          TextBlock { Text = $"#Name.Text, Mode=TwoWay" }
          TextBlock {
                  "Plain text"
                  Run { Background="Red" "Text" FontFamily="Tahoma" }
                  "Plain text"
          }
     }
     Styles = 
     {
          // Styles property is treated in specific way, all root elements are considered to be <Style Selector="{LINE}"> to reduce boilerplate
          StackPanel > is:(Control).someClass:pointerover
          {
                Margin = "0 0 1 4"
          }
          Button
          {
                Template =
                {
                     // ControlTemplate is omitted here and is assumed by default. We can probably do the same for regular XAML
                     ContentPresenter
                     {
                           Name = "PART_ContentPresenter"
                           Background = ${TemplateBinding Background}
                           TextBlock.Foreground = ${TemplateBinding Foreground}
                     }
                }
          }
     }
}

XAML for comparison:

<Window 
   xmlns="https://github.com/avaloniaui"
   xmlns:local="clr-namespace:MyNamespace"
   xmlns:lib="http://some.lib/xml/namespace"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:scg="clr-namespace:System.Collections.Generic;assembly=netstandard">
   xmlns:sys="clr-namespace:System;assembly=netstandard">
  <StackPanel 
     Orientation="Horizontal" Attached.Property="Value">
     <Button>
     <Button Background="Red">
        Click me
     </Button>
     <local:MyControl/>
     <lib:LibraryControl/>
     <scg:List x:TypeArguments="sys:Int32">
       <x:Int32>1</x:Int32>
       <x:Int32>2</x:Int32>
       <x:Int32>3</x:Int32>
       <x:Int32>4</x:Int32>
       <x:Int32>5</x:Int32>
       <x:Int32>6</x:Int32>
     </scg:List>
     <TextBlock Text="{Binding SomeVmProp}"/>
     <TextBlock x:Name="Name" Text="{Binding SomeVmProp}"/>
     <TextBlock Text="{Binding #Name.Text, Mode=TwoWay}"/>
     <TextBlock>
        Plain text
        <Run Background="Red" FontFamily="Tahoma">Text</Run>
        Plain text
     </TextBlock>
   </StackPanel>
   <Window.Styles>
      <Style Selector="StackPanel > is:(Control).someClass:pointerover">
          <Setter Property="Margin" Value="0 0 1 4"/>
      </Style>
      <Style Selector="Button">
         <Setter Property="Template">
            <ControlTemplate>
               <ContentPresenter 
                    Name="PART_ContentPresenter"
                    Background = "{TemplateBinding Background}"
                    TextBlock.Foreground = "{TemplateBinding Foreground}"/>
            </ControlTemplate>
         </Setter>
      </Style>
    </Window.Styles>
</Window>

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions