In part I, we created 2 Rebol Templates which generate a new form (.cs and .Designer.cs) within the Visual Studio Project directory. Unfortunately, Visual Studio doesn’t detect and ask if we would like to add them automatically. If we really want to do this manually, we have to automate further.
To do this, we just have to spy on how Visual Studio does it itself. When you add a new form to your project, Visual Studio will add the two .cs and .designer.cs files to the csproj.file just before the second </ItemGroup> XML tag so we will use this parse rule:
rule: [to </ItemGroup> thru </ItemGroup> thru <ItemGroup> to </ItemGroup> mark: (insert mark build-markup to-insert-template) thru </ItemGroup> to end]
Remark the syntax for inserting a code snippet: first mark the insert position with a variable (it could be mark: or any other name) then use parenthesis to execute rebol instructions to insert the snippet to-insert-template which content is following:
to-insert-template: { <Compile Include="<%Form-Name%>.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="<%Form-Name%>.Designer.cs">
<DependentUpon><%Form-Name%>.cs</DependentUpon>
</Compile>}
Last, we just need to search for .csproj file name among the list of files with
list-files: read to-rebol-file %../
foreach file list-files [if ((file-extension? file) = %.csproj) [csprojfile: file] ]
project-file: to-rebol-file rejoin ["../" csprojfile]
with file-extension? a usefull utility function to extract file extension:
file-extension?: func [File [url! file! string!] /local Ext][
parse/all File [some [thru #"."] [
thru #"/" | Ext: to end (Ext: to file! back Ext)
]] Ext
]
This is the whole program you should put in your Visual Studio Project Directory under any sub-directory (see previous lesson):
Rebol[]
Namespace: ask "Namespace: "
Form-Name: ask "Form Name: "
template: {
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace <%Namespace%>
{
public partial class <%Form-Name%> : Form
{
public <%Form-Name%>()
{
InitializeComponent();
}
}
}
}
template2: {
namespace <%Namespace%>
{
partial class <%Form-Name%>
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "<%Form-Name%>";
}
#endregion
}
}
}
to-insert-template: { <Compile Include="<%Form-Name%>.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="<%Form-Name%>.Designer.cs">
<DependentUpon><%Form-Name%>.cs</DependentUpon>
</Compile>}
file1: to-rebol-file rejoin ["../" Form-Name ".cs"]
file2: to-rebol-file rejoin ["../" Form-Name ".Designer.cs"]
write file1 build-markup template
write file2 build-markup template2
rule: [to </ItemGroup> thru </ItemGroup> thru <ItemGroup> to </ItemGroup> mark: (insert mark build-markup to-insert-template) thru </ItemGroup> to end]
file-extension?: func [File [url! file! string!] /local Ext][
parse/all File [some [thru #"."] [
thru #"/" | Ext: to end (Ext: to file! back Ext)
]] Ext
]
list-files: read to-rebol-file %../
foreach file list-files [if ((file-extension? file) = %.csproj) [csprojfile: file] ]
project-file: to-rebol-file rejoin ["../" csprojfile]
content: read project-file
parse content rule
if ((ask "Confirm (Y/N): ") = "Y") [
write project-file content
]
ask "Finished..."
If you run it, you should get something like this:




















Tags: C#, Code Generation, Parsing, Visual Studio, XML