Пример #1
0
        public void ProduceDefaultValues()
        {
            var parser = new MarkdownParser();

            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### Name [String] = PowerShell

```powershell
[Parameter(ParameterSetName = 'Set 1')]
```

";
            var          doc             = parser.ParseString(docFormatString);

            MamlCommand mamlCommand = (new ModelTransformer()).NodeModelToMamlModel(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(1, mamlCommand.Parameters.Count);
            var parameter = mamlCommand.Parameters[0];

            Assert.Equal(parameter.DefaultValue, "PowerShell");
        }
Пример #2
0
        public void ProducesParameterForDefaultParameterName()
        {
            var parser = new MarkdownParser();

            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### informationVariable

### force [switch]
```powershell
[Parameter(Mandatory=$false)]
```
";
            var          doc             = parser.ParseString(docFormatString);

            MamlCommand mamlCommand = (new ModelTransformer()).NodeModelToMamlModel(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(2, mamlCommand.Parameters.Count);

            var fooParam = mamlCommand.Parameters[0];

            Assert.Equal("informationVariable", fooParam.Name);
            Assert.Equal(null, fooParam.Type);
        }
Пример #3
0
        public void ProducesParameterValueGroup()
        {
            var parser = new MarkdownParser();

            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### foo [string]
```powershell
[ValidateSet('a', 'b', 'c')]
```
";
            var          doc             = parser.ParseString(docFormatString);

            MamlCommand mamlCommand = (new ModelTransformer()).NodeModelToMamlModel(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(1, mamlCommand.Syntax.Count);
            Assert.Equal(1, mamlCommand.Syntax[0].Parameters.Count);

            var fooParam = mamlCommand.Syntax[0].Parameters[0];

            Assert.Equal("foo", fooParam.Name);
            Assert.Equal("string", fooParam.Type);
            Assert.Equal(3, fooParam.ParameterValueGroup.Count);
            Assert.Equal("a", fooParam.ParameterValueGroup[0]);
            Assert.Equal("b", fooParam.ParameterValueGroup[1]);
            Assert.Equal("c", fooParam.ParameterValueGroup[2]);
        }
Пример #4
0
        private void AddExamples(MamlCommand command)
        {
            AddHeader(ModelTransformerBase.COMMAND_ENTRIES_HEADING_LEVEL, MarkdownStrings.EXAMPLES);
            foreach (var example in command.Examples)
            {
                var extraNewLine = ShouldBreak(example.FormatOption);

                AddHeader(ModelTransformerBase.EXAMPLE_HEADING_LEVEL, GetExampleTitle(example.Title), extraNewLine: extraNewLine);

                if (!string.IsNullOrEmpty(example.Introduction))
                {
                    AddParagraphs(example.Introduction);
                }

                if (example.Code != null)
                {
                    for (var i = 0; i < example.Code.Length; i++)
                    {
                        AddCodeSnippet(example.Code[i].Text, example.Code[i].LanguageMoniker);
                    }
                }

                if (!string.IsNullOrEmpty(example.Remarks))
                {
                    AddParagraphs(example.Remarks);
                }
            }
        }
Пример #5
0
        public void ProducesSyntaxInTheRightOrder()
        {
            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### SecondSetParam [String]

```powershell
[Parameter(ParameterSetName = 'Set 2')]
```

### FirstSetParam [String]

```powershell
[Parameter(ParameterSetName = 'Set 1')]
```

";
            var          doc             = ParseString(docFormatString);

            MamlCommand mamlCommand = NodeModelToMamlModelV1(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(2, mamlCommand.Syntax.Count);
            var syntax1 = mamlCommand.Syntax[0];
            var syntax2 = mamlCommand.Syntax[1];

            Assert.Equal(syntax1.Parameters.Count, 1);
            Assert.Equal(syntax2.Parameters.Count, 1);

            Assert.Equal(syntax1.Parameters[0].Name, "FirstSetParam");
            Assert.Equal(syntax2.Parameters[0].Name, "SecondSetParam");
        }
Пример #6
0
        public static string MamlModelToString(MamlCommand mamlCommand)
        {
            var serializer = new SerializerBuilder()
                             .WithNamingConvention(new CamelCaseNamingConvention())
                             .Build();

            var model = new YamlCommand
            {
                Name     = mamlCommand.Name,
                Notes    = mamlCommand.Notes,
                Remarks  = mamlCommand.Description,
                Summary  = mamlCommand.Synopsis,
                Examples = mamlCommand.Examples.Select(CreateExample).ToList(),
                Inputs   = mamlCommand.Inputs.Select(CreateInputOutput).ToList(),
                Links    = mamlCommand.Links.Select(CreateLink).ToList(),
                Module   = new YamlModule {
                    Name = mamlCommand.ModuleName
                },
                OptionalParameters = mamlCommand.Parameters.Where(p => !p.Required).Select(CreateParameter).ToList(),
                Outputs            = mamlCommand.Outputs.Select(CreateInputOutput).ToList(),
                RequiredParameters = mamlCommand.Parameters.Where(p => p.Required).Select(CreateParameter).ToList(),
                Syntaxes           = mamlCommand.Syntax.Select(CreateSyntax).ToList()
            };

            using (var writer = new StringWriter())
            {
                serializer.Serialize(writer, model);
                writer.Flush();
                return(writer.ToString());
            }
        }
Пример #7
0
        public void RendererNormalizeQuotesAndDashes()
        {
            var         renderer = new MarkdownV2Renderer(ParserMode.Full);
            MamlCommand command  = new MamlCommand()
            {
                Name        = "Test-Quotes",
                Synopsis    = new SectionBody("Example synopsis", SectionFormatOption.LineBreakAfterHeader),
                Description = new SectionBody(@"”“‘’––-")
            };

            string markdown = renderer.MamlModelToString(command, null);

            Common.AssertMultilineEqual(@"---
schema: 2.0.0
---

# Test-Quotes

## SYNOPSIS

Example synopsis

## DESCRIPTION
""""''---

## PARAMETERS

### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).

", markdown);
        }
Пример #8
0
        public void ProducesParameterValueGroup()
        {
            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### foo
```yaml
Type: string
Accepted values: a, b, c
```
";
            var          doc             = ParseString(docFormatString);

            MamlCommand mamlCommand = NodeModelToMamlModelV2(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(1, mamlCommand.Syntax.Count);
            Assert.Equal(1, mamlCommand.Syntax[0].Parameters.Count);

            var fooParam = mamlCommand.Syntax[0].Parameters[0];

            Assert.Equal("foo", fooParam.Name);
            Assert.Equal("string", fooParam.Type);
            Assert.Equal(3, fooParam.ParameterValueGroup.Count);
            Assert.Equal("a", fooParam.ParameterValueGroup[0]);
            Assert.Equal("b", fooParam.ParameterValueGroup[1]);
            Assert.Equal("c", fooParam.ParameterValueGroup[2]);
        }
Пример #9
0
        public void ProducesParameterForDefaultParameterName()
        {
            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### informationVariable

### force

```yaml
Type: SwitchParameter
Required: false
```
";
            var          doc             = ParseString(docFormatString);

            MamlCommand mamlCommand = NodeModelToMamlModelV2(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(2, mamlCommand.Parameters.Count);

            var informationVariable = mamlCommand.Parameters[0];

            Assert.Equal("informationVariable", informationVariable.Name);
            Assert.Equal(null, informationVariable.Type);
            Assert.Equal(true, informationVariable.ValueRequired);

            var force = mamlCommand.Parameters[1];

            Assert.Equal("force", force.Name);
            Assert.Equal("SwitchParameter", force.Type);
            Assert.Equal(false, force.ValueRequired);
        }
Пример #10
0
        public void UsesEntryToMarkGlobbing()
        {
            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### Name

```yaml
Type: string
Accept wildcard characters: true
```

";
            var          doc             = ParseString(docFormatString);

            MamlCommand mamlCommand = NodeModelToMamlModelV2(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(1, mamlCommand.Parameters.Count);
            var parameter = mamlCommand.Parameters[0];

            Assert.True(parameter.Globbing);
            Assert.Equal(parameter.Type, "string");
        }
Пример #11
0
        public void ProduceDefaultValues()
        {
            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### Name

```yaml
Type: String
Parameter Sets: Set1
Aliases: 

Required: False
Position: Named
Default value: PowerShell
Accept pipeline input: False
Accept wildcard characters: False
```

";
            var          doc             = ParseString(docFormatString);

            MamlCommand mamlCommand = NodeModelToMamlModelV2(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(1, mamlCommand.Parameters.Count);
            var parameter = mamlCommand.Parameters[0];

            Assert.Equal(parameter.DefaultValue, "PowerShell");
        }
Пример #12
0
        public void PreserveFormattingIfNeeded()
        {
            const string description = @"Hello

This description block test formatting preservance.
-- It need to
-- Be. Very. [Weiredly](formatted)



\< to keep > the purpose. \\( \\\( \(
   This is intentional.
* we

* dont't want. * Mess up with user's formatting.
";

            const string docFormatString = @"
# Get-Foo
## DESCRIPTION
" + description;
            var          doc             = ParseStringPreserveFormat(docFormatString);

            MamlCommand mamlCommand = NodeModelToMamlModelV2(doc).First();

            Assert.Equal("Get-Foo", mamlCommand.Name);

            Assert.Equal(description, mamlCommand.Description);
        }
Пример #13
0
        private static XElement CreateCommandElement(MamlCommand command)
        {
            var commandParts = command.Name.Split('-');
            var verb         = commandParts[0];
            var noun         = command.Name.Substring(Math.Min(verb.Length + 1, command.Name.Length));

            return(new XElement(commandNS + "command",
                                new XAttribute(XNamespace.Xmlns + "maml", mamlNS),
                                new XAttribute(XNamespace.Xmlns + "command", commandNS),
                                new XAttribute(XNamespace.Xmlns + "dev", devNS),
                                new XAttribute(XNamespace.Xmlns + "MSHelp", msHelpNS),

                                new XElement(commandNS + "details",
                                             new XElement(commandNS + "name", command.Name),
                                             new XElement(commandNS + "verb", verb),
                                             new XElement(commandNS + "noun", noun),
                                             new XElement(mamlNS + "description", GenerateParagraphs(command.Synopsis?.Text))),
                                new XElement(mamlNS + "description", GenerateParagraphs(command.Description?.Text)),
                                new XElement(commandNS + "syntax", command.Syntax.Select(syn => CreateSyntaxItem(syn, command))),
                                new XElement(commandNS + "parameters", command.Parameters.Select(param => CreateParameter(param))),
                                new XElement(commandNS + "inputTypes", command.Inputs.Select(input => CreateInput(input))),
                                new XElement(commandNS + "returnValues", command.Outputs.Select(output => CreateOutput(output))),
                                new XElement(mamlNS + "alertSet",
                                             new XElement(mamlNS + "alert", GenerateParagraphs(command.Notes?.Text))),
                                new XElement(commandNS + "examples", command.Examples.Select(example => CreateExample(example))),
                                new XElement(commandNS + "relatedLinks", command.Links.Select(link => CreateLink(link)))));
        }
Пример #14
0
        public void ReturnsSyntaxString()
        {
            var command = new MamlCommand()
            {
                Name = "Get-Foo",
                SupportCommonParameters = true
            };

            var param1 = new MamlParameter()
            {
                Name = "Bar",
                Type = "BarObject"
            };

            var syntax = new MamlSyntax()
            {
                IsDefault = true
            };

            syntax.Parameters.Add(param1);

            string syntaxString = MarkdownV2Renderer.GetSyntaxString(command, syntax);

            Assert.Equal("Get-Foo [-Bar <BarObject>] [<CommonParameters>]", syntaxString);
        }
Пример #15
0
        public void UsesSupportsWildCardsToMarkGlobbing()
        {
            var parser = new MarkdownParser();

            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### Name [String]

```
[SupportsWildCards()]
```

";
            var          doc             = parser.ParseString(docFormatString);

            MamlCommand mamlCommand = (new ModelTransformer()).NodeModelToMamlModel(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(1, mamlCommand.Parameters.Count);
            var parameter = mamlCommand.Parameters[0];

            Assert.True(parameter.Globbing);
            Assert.Equal(parameter.Type, "String");
        }
        private void GatherSyntax(MamlCommand command)
        {
            var parameterSetNames = GetParameterSetNames();

            if (parameterSetNames.Count == 0)
            {
                // special case: there are no parameters and hence there is only one parameter set
                MamlSyntax syntax = new MamlSyntax();
                command.Syntax.Add(syntax);
            }

            foreach (var setName in parameterSetNames)
            {
                MamlSyntax syntax = new MamlSyntax();
                if (setName == ALL_PARAM_SETS_MONIKER)
                {
                    if (parameterSetNames.Count == 1)
                    {
                        // special case: there is only one parameter set and it's the deafult one
                        // we don't specify the name in this case.
                    }
                    else
                    {
                        continue;
                    }
                }
                else
                {
                    syntax.ParameterSetName = setName;
                }

                FillUpSyntax(syntax, setName);
                command.Syntax.Add(syntax);
            }
        }
Пример #17
0
        private void AddLinks(int levelRoot, MamlCommand command)
        {
            if (command.Links != null && command.Links.Count > 0)
            {
                AddHeader(levelRoot, ModelTransformerBase.COMMAND_ENTRIES_HEADING_LEVEL, MarkdownStrings.RELATED_LINKS, extraNewLine: true);
                foreach (var link in command.Links)
                {
                    if (link.IsSimplifiedTextLink)
                    {
                        _stringBuilder.AppendFormat("{0}", link.LinkName);
                    }
                    else
                    {
                        var name = link.LinkName;
                        if (string.IsNullOrEmpty(name))
                        {
                            // we need a valid name to produce a valid markdown
                            name = link.LinkUri;
                        }

                        _stringBuilder.AppendFormat("[{0}]({1}){2}{2}", name, link.LinkUri, NewLine);
                    }
                }
            }
        }
Пример #18
0
        public MamlCommand Merge(Dictionary <string, MamlCommand> applicableTag2Model)
        {
            if (applicableTag2Model.Count == 0)
            {
                throw new ArgumentException("applicableTag2Model");
            }

            var tagsModel = applicableTag2Model.ToList();

            // just take one model to use name from it and such
            var referenceModel = applicableTag2Model.First().Value;

            MamlCommand result = null;

            result = new MamlCommand()
            {
                Name        = referenceModel.Name,
                Synopsis    = new SectionBody(MergeText(tagsModel.ToDictionary(pair => pair.Key, pair => pair.Value.Synopsis.Text))),
                Description = new SectionBody(MergeText(tagsModel.ToDictionary(pair => pair.Key, pair => pair.Value.Description.Text))),
                Notes       = new SectionBody(MergeText(tagsModel.ToDictionary(pair => pair.Key, pair => pair.Value.Notes.Text))),
                Extent      = referenceModel.Extent
            };

            result.Links.AddRange(MergeSimplifiedLinks(tagsModel.Select(pair => pair.Value.Links)));

            MergeExamples(result, applicableTag2Model);

            result.Inputs.AddRange(MergeEntityList(tagsModel.Select(pair => pair.Value.Inputs)));
            result.Outputs.AddRange(MergeEntityList(tagsModel.Select(pair => pair.Value.Outputs)));

            MergeParameters(result, applicableTag2Model);
            return(result);
        }
        public void TransformCommandWithParameterHeaderLineBreak()
        {
            var         doc         = ParseString(@"
# Add-Member

## PARAMETERS

### -Name

This is the name parameter.

```yaml
Type: String
Parameter Sets: (All)
Aliases:

Required: True
Position: 0
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
");
            MamlCommand mamlCommand = NodeModelToMamlModelV2(doc).First();

            Assert.Equal("This is the name parameter.", mamlCommand.Parameters[0].Description);
            Assert.Equal(SectionFormatOption.LineBreakAfterHeader, mamlCommand.Parameters[0].FormatOption);
        }
Пример #20
0
        private void RelatedLinksRule(MamlCommand commmand)
        {
            var paragraphNode = ParagraphNodeRule();

            if (paragraphNode == null)
            {
                return;
            }

            foreach (var paragraphSpan in paragraphNode.Spans)
            {
                var linkSpan = paragraphSpan as HyperlinkSpan;
                if (linkSpan != null)
                {
                    commmand.Links.Add(new MamlLink()
                    {
                        LinkName = linkSpan.Text,
                        LinkUri  = linkSpan.Uri
                    });
                }
                else
                {
                    throw new HelpSchemaException(paragraphSpan.SourceExtent, "Expect hyperlink, but got " + paragraphSpan.Text);
                }
            }
        }
Пример #21
0
        public void RendererCreatesWorkflowParametersEntryWithoutDescriptions()
        {
            var         renderer = new MarkdownV2Renderer(ParserMode.Full);
            MamlCommand command  = new MamlCommand()
            {
                Name       = "Workflow",
                IsWorkflow = true
            };

            command.Syntax.Add(new MamlSyntax());

            string markdown = renderer.MamlModelToString(command, null);

            Common.AssertMultilineEqual(@"---
schema: 2.0.0
---

# Workflow

## SYNTAX

```
Workflow [<WorkflowCommonParameters>] [<CommonParameters>]
```

## PARAMETERS

### WorkflowCommonParameters
This cmdlet supports the following workflow common parameters: -PSParameterCollection, -PSComputerName, -PSCredential, -PSConnectionRetryCount, -PSConnectionRetryIntervalSec, -PSRunningTimeoutSec, -PSElapsedTimeoutSec, -PSPersist, -PSAuthentication, -PSAuthenticationLevel, -PSApplicationName, -PSPort, -PSUseSSL, -PSConfigurationName, -PSConnectionURI, -PSAllowRedirection, -PSSessionOption, -PSCertificateThumbprint, -PSPrivateMetadata, -AsJob, -JobName, and -InputObject. For more information, see [about_WorkflowCommonParameters](http://go.microsoft.com/fwlink/p/?LinkID=533952).

### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).

", markdown);
        }
Пример #22
0
        private void AddLinks(MamlCommand command)
        {
            PushTag("command:relatedLinks");
            foreach (MamlLink Link in command.Links)
            {
                if (Link.IsSimplifiedTextLink)
                {
                    // that should never happen.
                    // we don't know how to represent non-parsed links in maml.
                    // skipping it.
                    // TODO: error out?
                    continue;
                }

                PushTag("maml:navigationLink");

                PushTag("maml:linkText");
                _stringBuilder.Append(XmlEscape(Link.LinkName));
                PopTag(1);

                PushTag("maml:uri");
                _stringBuilder.Append(XmlEscape(Link.LinkUri));
                PopTag(1);

                PopTag(1);
            }
            PopTag(1);
        }
Пример #23
0
        public void ProducesSyntaxForTwoSets()
        {
            const string docFormatString = @"
# Get-Foo
## PARAMETERS

### TypeName [String]

```powershell
[Parameter(Mandatory = $true, ParameterSetName = 'Set 1')]
[Parameter(ParameterSetName = 'Set 2')]
```
";
            var          doc             = ParseString(docFormatString);

            MamlCommand mamlCommand = NodeModelToMamlModelV1(doc).First();

            Assert.Equal(mamlCommand.Name, "Get-Foo");

            Assert.Equal(2, mamlCommand.Syntax.Count);
            var syntax1 = mamlCommand.Syntax[0];
            var syntax2 = mamlCommand.Syntax[1];

            Assert.Equal(syntax1.Parameters.Count, 1);
            Assert.Equal(syntax2.Parameters.Count, 1);

            Assert.Equal(syntax1.Parameters[0].Name, "TypeName");
            Assert.Equal(syntax2.Parameters[0].Name, "TypeName");

            Assert.Equal(syntax1.Parameters[0].Type, "String");
            Assert.Equal(syntax2.Parameters[0].Type, "String");

            Assert.Equal(syntax1.Parameters[0].Required, false);
            Assert.Equal(syntax2.Parameters[0].Required, true);
        }
Пример #24
0
        public void RendererProduceNameAndSynopsis()
        {
            MamlRenderer renderer = new MamlRenderer();
            MamlCommand  command  = new MamlCommand()
            {
                Name        = "Get-Foo",
                Synopsis    = "This is the synopsis",
                Description = "This is a long description."
            };

            command.Parameters.Add(new MamlParameter()
            {
                Type           = "String",
                Name           = "Name",
                Required       = true,
                Description    = "Parameter Description.",
                VariableLength = true,
                Globbing       = true,
                PipelineInput  = "True (ByValue)",
                Position       = "1",
                Aliases        = new string [] { "GF", "Foos", "Do" },
            }
                                   );
            command.Inputs.Add(new MamlInputOutput()
            {
                TypeName    = "String",
                Description = "Input Description goes here!"
            }
                               );
            command.Outputs.Add(new MamlInputOutput()
            {
                TypeName    = "String",
                Description = "Output Description goes here!"
            }
                                );
            command.Examples.Add(new MamlExample()
            {
                Title   = "Example 1",
                Code    = "PS:> Get-Help -YouNeedIt",
                Remarks = "This does stuff!"
            }
                                 );
            command.Links.Add(new MamlLink()
            {
                LinkName = "PowerShell made by Microsoft Hackathon",
                LinkUri  = "www.microsoft.com"
            }
                              );

            string maml = renderer.MamlModelToString(new [] { command });

            string[] name = EndToEndTests.GetXmlContent(maml, "/helpItems/command:command/command:details/command:name");
            Assert.Equal(1, name.Length);
            Assert.Equal("Get-Foo", name[0]);

            string[] synopsis = EndToEndTests.GetXmlContent(maml, "/helpItems/command:command/command:details/maml:description/maml:para");
            Assert.Equal(1, synopsis.Length);
            Assert.Equal("This is the synopsis", synopsis[0]);
        }
Пример #25
0
        protected void ParametersRule(MamlCommand command)
        {
            while (ParameterRule(command))
            {
            }

            GatherSyntax(command);
        }
Пример #26
0
 private void AddInputs(MamlCommand command)
 {
     AddHeader(ModelTransformerBase.COMMAND_ENTRIES_HEADING_LEVEL, MarkdownStrings.INPUTS);
     foreach (var io in command.Inputs)
     {
         AddInputOutput(io);
     }
 }
Пример #27
0
 private void AddNotes(MamlCommand command)
 {
     PushTag("maml:alertSet");
     PushTag("maml:alert");
     AddParas(command.Notes);
     PopTag("maml:alert");
     PopTag("maml:alertSet");
 }
Пример #28
0
        private void ParametersRule(MamlCommand commmand)
        {
            while (ParameterRule(commmand))
            {
            }

            this.GatherParameterDetails(commmand);
        }
Пример #29
0
        public void RenderesWithPreservedFormatting()
        {
            var         renderer = new MarkdownV2Renderer(ParserMode.FormattingPreserve);
            MamlCommand command  = new MamlCommand()
            {
                Name = "Get-Foo",
                SupportCommonParameters = false,
                Description             = new SectionBody(@"Hello
This \<description \> should be preserved by renderer
With all [hyper](https://links.com) and yada
  -- yada

* Also
* This list. May look. A little
weired
* [ ] But

* [ ] It should be left"
                                                          )
            };

            command.Links.Add(
                new MamlLink(isSimplifiedTextLink: true)
            {
                LinkName = "Any text [can](go here)\r\n[any](text)"
            }
                );

            string markdown = renderer.MamlModelToString(command, null);

            Common.AssertMultilineEqual(@"---
schema: 2.0.0
---

# Get-Foo

## SYNOPSIS

## SYNTAX

## DESCRIPTION
" + command.Description + @"

## EXAMPLES

## PARAMETERS

## INPUTS

## OUTPUTS

## NOTES

## RELATED LINKS

Any text [can](go here)
[any](text)", markdown);
        }
Пример #30
0
        protected void ExamplesRule(MamlCommand commmand)
        {
            MamlExample example;

            while ((example = ExampleRule()) != null)
            {
                commmand.Examples.Add(example);
            }
        }
Пример #31
0
        public IEnumerable<MamlCommand> NodeModelToMamlModel(DocumentNode node)
        {
            _root = node;
            if (_root.Children == null)
            {
                // HACK:
                _rootEnumerator = (new LinkedList<MarkdownNode>()).GetEnumerator();
            }
            else
            {
                _rootEnumerator = _root.Children.GetEnumerator();
            }

            List<MamlCommand> commands = new List<MamlCommand>();
            MarkdownNode markdownNode;
            while ((markdownNode = GetNextNode()) != null)
            {
                if (markdownNode is HeadingNode)
                {
                    var headingNode = markdownNode as HeadingNode;
                    switch (headingNode.HeadingLevel)
                    {
                        case COMMAND_NAME_HEADING_LEVEL:
                            {
                                MamlCommand command = new MamlCommand()
                                {
                                    Name = headingNode.Text,
                                    Extent = headingNode.SourceExtent
                                };

                                if (_infoCallback != null)
                                {
                                    Console.WriteLine("Start processing command " + command.Name);
                                }

                                // fill up command 
                                while (SectionDispatch(command)) { }

                                commands.Add(command);
                                break;
                            }
                        default: throw new HelpSchemaException(headingNode.SourceExtent, "Booo, I don't know what is the heading level " + headingNode.HeadingLevel);
                    }
                }
            }
            return commands;
        }
Пример #32
0
        public void RendererProduceSyntaxAndParameter()
        {
            MamlRenderer renderer = new MamlRenderer();
            MamlCommand command = new MamlCommand()
            {
                Name = "Get-Foo",
            };

            var param1 = new MamlParameter()
            {
                Type = "String",
                Name = "Param1",
                Position = "Named"
            };

            var param2 = new MamlParameter()
            {
                Type = "System.Int32",
                Name = "Param2",
                Position = "Named"
            };

            command.Parameters.Add(param1);
            command.Parameters.Add(param2);

            var syntax = new MamlSyntax();
            syntax.Parameters.Add(param1);
            syntax.Parameters.Add(param2);
            command.Syntax.Add(syntax);

            string maml = renderer.MamlModelToString(new[] { command });

            string[] syntaxItemName = EndToEndTests.GetXmlContent(maml, "/helpItems/command:command/command:syntax/command:syntaxItem/maml:name");
            Assert.Equal(1, syntaxItemName.Length);
            Assert.Equal("Get-Foo", syntaxItemName[0]);

            string[] nameSyntax = EndToEndTests.GetXmlContent(maml, "/helpItems/command:command/command:syntax/command:syntaxItem/command:parameter/maml:name");
            Assert.Equal(2, nameSyntax.Length);
            Assert.Equal("Param1", nameSyntax[0]);
            Assert.Equal("Param2", nameSyntax[1]);

            string[] nameParam = EndToEndTests.GetXmlContent(maml, "/helpItems/command:command/command:parameters/command:parameter/maml:name");
            Assert.Equal(2, nameParam.Length);
            Assert.Equal("Param1", nameParam[0]);
            Assert.Equal("Param2", nameParam[1]);
        }
Пример #33
0
        private void AddParameter(MamlCommand command, MamlParameter parameter, bool inSyntax)
        {
            var attributes = "required=\"" + parameter.Required.ToString().ToLower() + "\" " +
                             "variableLength=\"" + parameter.VariableLength.ToString().ToLower() + "\" " +
                             "globbing=\"" + parameter.Globbing.ToString().ToLower() + "\" " +
                             "pipelineInput=\"" + parameter.PipelineInput + "\" " +
                             "position=\"" + parameter.Position.ToLower() + "\" " +
                             "aliases=\"";
            attributes += parameter.Aliases.Length > 0 ? string.Join(", ", parameter.Aliases) : "none";
            attributes += "\"";

            PushTag("command:parameter", attributes);

            PushTag("maml:name");
            _stringBuilder.Append(XmlEscape(parameter.Name));
            PopTag("maml:name");

            PushTag("maml:Description");
            AddParas(parameter.Description);
            PopTag("maml:Description");

            if (inSyntax && parameter.ParameterValueGroup.Count > 0)
            {
                AddParameterValueGroup(parameter.ParameterValueGroup);
            }

            attributes = "required=\"" + parameter.ValueRequired.ToString().ToLower() + "\" " +
                         "variableLength=\"" + parameter.ValueVariableLength.ToString().ToLower();
            attributes += "\"";

            string mamlType = ConvertPSTypeToMamlType(parameter.Type);

            // this is weired quirk inside <syntax>:
            // we don't add [switch] info to make it appear good.
            if (!inSyntax || mamlType != "SwitchParameter")
            {
                PushTag("command:parameterValue", attributes);
                _stringBuilder.Append(XmlEscape(mamlType));
                PopTag("command:parameterValue");
            }

            PushTag("dev:type");
            PushTag("maml:name");
            _stringBuilder.Append(XmlEscape(mamlType));
            PopTag("maml:name");
            _stringBuilder.Append("<maml:uri />");
            PopTag("dev:type");

            // Region defaultValue

            PushTag("dev:defaultValue");

            if (mamlType == "SwitchParameter" && parameter.DefaultValue == null)
            {
                _stringBuilder.Append("False");
            }
            else
            {
                if (parameter.DefaultValue != null)
                {
                    _stringBuilder.Append(XmlEscape(parameter.DefaultValue));
                }
                else
                {
                    // sometimes default is none, but empty makes more sense.
                    // _stringBuilder.Append("none");
                }
            }

            PopTag("dev:defaultValue");
            // closing tag
            PopTag("command:parameter");
        }
Пример #34
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns>true if Section was found</returns>
        private bool SectionDispatch(MamlCommand command)
        {
            var node = GetNextNode();
            var headingNode = GetHeadingWithExpectedLevel(node, COMMAND_ENTRIES_HEADING_LEVEL);
            if (headingNode == null)
            {
                return false;
            }

            switch (headingNode.Text.ToUpper())
            {
                case "DESCRIPTION":
                    {
                        command.Description = SimpleTextSectionRule();
                        break;
                    }
                case "SYNOPSIS":
                    {
                        command.Synopsis = SimpleTextSectionRule();
                        break;
                    }
                case "PARAMETERS":
                    {
                        ParametersRule(command);
                        break;
                    }
                case "INPUTS":
                    {
                        InputsRule(command);
                        break;
                    }
                case "OUTPUTS":
                    {
                        OutputsRule(command);
                        break;
                    }
                case "NOTES":
                    {
                        command.Notes = SimpleTextSectionRule();
                        break;
                    }
                case "EXAMPLES":
                    {
                        ExamplesRule(command);
                        break;
                    }
                case "RELATED LINKS":
                    {
                        RelatedLinksRule(command);
                        break;
                    }
                default:
                    {
                        throw new HelpSchemaException(headingNode.SourceExtent, "Unexpected header name " + headingNode.Text);
                    }
            }
            return true;
        }
Пример #35
0
        public void RendererProduceNameAndSynopsis()
        {
            MamlRenderer renderer = new MamlRenderer();
            MamlCommand command = new MamlCommand()
            {
                Name = "Get-Foo",
                Synopsis = "This is the synopsis",
                Description = "This is a long description."
            };

            command.Parameters.Add(new MamlParameter()
            {
                Type = "String",
                Name = "Name",
                Required = true,
                Description = "Parameter Description.",
                VariableLength = true,
                Globbing = true,
                PipelineInput = "True (ByValue)",
                Position = "1",
                Aliases = new string []{"GF","Foos","Do"},
            }
            );
            command.Inputs.Add(new MamlInputOutput()
            {
                    TypeName = "String",
                    Description = "Input Description goes here!"
                    
            }
            );
            command.Outputs.Add(new MamlInputOutput()
            {
                TypeName = "String",
                Description = "Output Description goes here!"
            }
            );
            command.Examples.Add(new MamlExample()
            {
                Title = "Example 1",
                Code = "PS:> Get-Help -YouNeedIt",
                Remarks = "This does stuff!"
            }
            );
            command.Links.Add(new MamlLink()
            {
                    LinkName = "PowerShell made by Microsoft Hackathon",
                    LinkUri = "www.microsoft.com"
                    
            }
            );

            string maml = renderer.MamlModelToString(new [] {command});

            string[] name = EndToEndTests.GetXmlContent(maml, "/helpItems/command:command/command:details/command:name");
            Assert.Equal(1, name.Length);
            Assert.Equal("Get-Foo", name[0]);

            string[] synopsis = EndToEndTests.GetXmlContent(maml, "/helpItems/command:command/command:details/maml:description/maml:para");
            Assert.Equal(1, synopsis.Length);
            Assert.Equal("This is the synopsis", synopsis[0]);
        }
Пример #36
0
        private void AddExamples(MamlCommand command)
        {
            PushTag("command:examples");
            foreach (MamlExample example in command.Examples)
            {
                PushTag("command:example");

                PushTag("maml:title");
                _stringBuilder.Append(XmlEscape(example.Title));
                PopTag("maml:title");

                PushTag("dev:code");
                _stringBuilder.Append(XmlEscape(example.Code));
                PopTag("dev:code");

                PushTag("dev:remarks");
                AddParas(example.Remarks);
                PopTag("dev:remarks");

                PopTag("command:example");
            }
            PopTag("command:examples");
        }
Пример #37
0
 private void AddSyntax(MamlCommand command)
 {
     PushTag("command:syntax");
     foreach (MamlSyntax syntaxItem in command.Syntax)
     {
         PushTag("command:syntaxItem");
         _stringBuilder.AppendFormat("<maml:name>{0}</maml:name>{1}", XmlEscape(command.Name), Environment.NewLine);
         foreach (MamlParameter parameter in syntaxItem.Parameters)
         {
             AddParameter(command, parameter, inSyntax: true);
         }
         PopTag("command:syntaxItem");
     }
     PopTag("command:syntax");
 }
Пример #38
0
 private void AddParameters(MamlCommand command)
 {
     PushTag("command:parameters");
     foreach (MamlParameter parameter in command.Parameters)
     {
         AddParameter(command, parameter, inSyntax:false);
     }
     PopTag("command:parameters");
 }
Пример #39
0
        private void AddOutputs(MamlCommand command)
        {
            PushTag("command:returnValues");
            foreach (var output in command.Outputs)
            {
                PushTag("command:returnValue");

                PushTag("dev:type");
                PushTag("maml:name");
                _stringBuilder.Append(XmlEscape(output.TypeName));
                PopTag("maml:name");
                PopTag("dev:type");

                PushTag("maml:description");
                AddParas(output.Description);
                PopTag("maml:description");

                PopTag("command:returnValue");
            }
            PopTag("command:returnValues");
        }
Пример #40
0
        private void RelatedLinksRule(MamlCommand commmand)
        {
            var paragraphNode = ParagraphNodeRule();
            if (paragraphNode == null)
            {
                return;
            }

            foreach (var paragraphSpan in paragraphNode.Spans)
            {
                var linkSpan = paragraphSpan as HyperlinkSpan;
                if (linkSpan != null)
                {
                    commmand.Links.Add(new MamlLink()
                    {
                        LinkName = linkSpan.Text,
                        LinkUri = linkSpan.Uri
                    });
                }
                else
                {
                    throw new HelpSchemaException(paragraphSpan.SourceExtent, "Expect hyperlink, but got " + paragraphSpan.Text);
                }
            }
        }
Пример #41
0
        private void ParametersRule(MamlCommand commmand)
        {
            while (ParameterRule(commmand))
            {
            }

            this.GatherParameterDetails(commmand);
        }
Пример #42
0
 private void InputsRule(MamlCommand commmand)
 {
     MamlInputOutput input;
     while ((input = InputOutputRule()) != null)
     {
         commmand.Inputs.Add(input);
     }
 }
Пример #43
0
 private void OutputsRule(MamlCommand commmand)
 {
     MamlInputOutput output;
     while ((output = InputOutputRule()) != null)
     {
         commmand.Outputs.Add(output);
     }
 }
Пример #44
0
 private void ExamplesRule(MamlCommand commmand)
 {
     MamlExample example;
     while ((example = ExampleRule()) != null)
     {
         commmand.Examples.Add(example);
     }
 }
Пример #45
0
        private void AddInputs(MamlCommand command)
        {
            PushTag("command:inputTypes");
            foreach (var input in command.Inputs)
            {
                PushTag("command:inputType");

                PushTag("dev:type");
                PushTag("maml:name");
                _stringBuilder.Append(XmlEscape(input.TypeName));
                PopTag("maml:name");
                PopTag("dev:type");

                PushTag("maml:description");
                AddParas(input.Description);
                PopTag("maml:description");

                PopTag("command:inputType");
            }
            PopTag("command:inputTypes");
        }
Пример #46
0
 private void AddDescription(MamlCommand command)
 {
     PushTag("maml:description");
     AddParas(command.Description);
     PopTag(1);
 }
Пример #47
0
 private void AddNotes(MamlCommand command)
 {
     PushTag("maml:alertSet");
     PushTag("maml:alert");
     AddParas(command.Notes);
     PopTag("maml:alert");
     PopTag("maml:alertSet");
 }
Пример #48
0
 private void AddSynopsis(MamlCommand command)
 {
     PushTag("maml:description");
     AddParas(command.Synopsis);
     PopTag(1);
 }
Пример #49
0
        private void AddLinks(MamlCommand command)
        {
            PushTag("command:relatedLinks");
            foreach (MamlLink Link in command.Links)
            {
                PushTag("maml:navigationLink");

                PushTag("maml:linkText");
                _stringBuilder.Append(XmlEscape(Link.LinkName));
                PopTag(1);

                PushTag("maml:uri");
                _stringBuilder.Append(XmlEscape(Link.LinkUri));
                PopTag(1);

                PopTag(1);
            }
            PopTag(1);
        }
Пример #50
0
        public void RendererProduceEscapeXmlSpecialChars()
        {
            MamlRenderer renderer = new MamlRenderer();
            MamlCommand command = new MamlCommand()
            {
                Name = "Get-Foo",
                Synopsis = "<port&number>" // < and > should be properly escaped
            };
            
            string maml = renderer.MamlModelToString(new[] { command });

            string[] synopsis = EndToEndTests.GetXmlContent(maml, "/helpItems/command:command/command:details/maml:description/maml:para");
            Assert.Equal(1, synopsis.Length);
            Assert.Equal(synopsis[0], command.Synopsis);
        }
Пример #51
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns>true if Parameter was found</returns>
        private bool ParameterRule(MamlCommand command)
        {
            // grammar:
            // #### Name [TypeName]     -   mandatory
            // ```powershell            -   optional
            // [Parameter(...)]
            // ```
            // Description              -   optional
            var node = GetNextNode();
            var headingNode = GetHeadingWithExpectedLevel(node, PARAMETER_NAME_HEADING_LEVEL);
            if (headingNode == null)
            {
                return false;
            }

            var name = headingNode.Text.Split()[0];
            
            MamlParameter parameter = new MamlParameter()
            {
                Name = name,
                Extent = headingNode.SourceExtent
            };

            int equalIndex = headingNode.Text.IndexOf('=');
            string headingNodeText;
            if (equalIndex >= 0)
            {
                parameter.DefaultValue = headingNode.Text.Substring(equalIndex + 1).Trim();
                // trim it for this case from PSReadLine:
                // #### WordDelimiters [Int32] = ;:,.[]{}()/\|^&*-=+
                // We need to make sure that closing ] corresponds to [Int32], so it's the last ] before first = sign.
                headingNodeText = headingNode.Text.Substring(0, equalIndex);
            }
            else
            {
                headingNodeText = headingNode.Text;
            }

            int typeBeginIndex = headingNodeText.IndexOf('[');
            int typeEndIndex = headingNodeText.LastIndexOf(']');
            if (typeBeginIndex >= 0 && typeEndIndex > 0)
            {
                parameter.Type = headingNodeText.Substring(typeBeginIndex + 1, typeEndIndex - typeBeginIndex - 1);
            }

            node = GetNextNode();

            ParagraphNode descriptionNode = null;
            CodeBlockNode attributesNode = null;

            // it can be the end
            if (node != null)
            {
                switch (node.NodeType)
                {
                    case MarkdownNodeType.Unknown:
                        break;
                    case MarkdownNodeType.Document:
                        break;
                    case MarkdownNodeType.Paragraph:
                        descriptionNode = node as ParagraphNode;
                        break;
                    case MarkdownNodeType.Heading:
                        // next parameter started
                        UngetNode(node);
                        break;
                    case MarkdownNodeType.CodeBlock:
                        attributesNode = node as CodeBlockNode;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }

                if (descriptionNode == null)
                {
                    descriptionNode = ParagraphNodeRule();
                }
            }

            parameter.Description = GetTextFromParagraphNode(descriptionNode);
            parameter.AttributesText = 
                attributesNode != null ?
                    attributesNode.Text : string.Empty;

            if (parameter.AttributesText.Contains(@"[SupportsWildCards()]"))
            {
                parameter.Globbing = true;
            }

            command.Parameters.Add(parameter);
            return true;
        }
Пример #52
0
        private void GatherParameterDetails(MamlCommand command)
        {
            const string parameterFormatString = @"
        {0}
        ${1}";

            const string docFunctionFormatString = @"
function Get-AttributeDocFunction
{{
    param(
        {0}
    )

}}

$h = Get-Help Get-AttributeDocFunction
$h.parameters.parameter
";

            // Create the Runspace on demand
            if (this.runspace == null)
            {
                this.runspace = RunspaceFactory.CreateRunspace();
                this.runspace.Open();
            }

            using (PowerShell powerShell = PowerShell.Create())
            {
                var parameterBlocks =
                    command
                        .Parameters
                        .Select(p => string.Format(parameterFormatString, p.AttributesText, ShiftName(p.Name)));

                var functionScript =
                    string.Format(
                        docFunctionFormatString,
                        string.Join(",\r\n", parameterBlocks));

                // TODO: There could be some security concerns with executing arbitrary
                // text here, need to investigate safer ways to do it.  JEA?
                powerShell.Runspace = this.runspace;
                powerShell.AddScript(functionScript);
                var parameterDetailses = powerShell.Invoke<PSObject>();
                if (powerShell.Streams.Error.Any())
                {
                    throw new HelpSchemaException(command.Extent, "Errors when processing command " + command.Name + ":\n" + string.Join(";\n", powerShell.Streams.Error));    
                }

                foreach (PSObject parameterDetailsPsObject in parameterDetailses)
                {
                    var parameter = 
                        command.Parameters.FirstOrDefault(
                            p => string.Equals(p.Name, UndoShiftName((string)parameterDetailsPsObject.Properties["name"].Value)));

                    FillUpParameterFromPSObject(parameter, parameterDetailsPsObject);
                }

                powerShell.Commands.Clear();
                powerShell.Commands.AddScript("$h.Syntax.syntaxItem");
                var syntaxDetailses = powerShell.Invoke<PSObject>();
                if (powerShell.Streams.Error.Any())
                {
                    throw new HelpSchemaException(command.Extent, "Errors when processing command " + command.Name + ":\n" + string.Join(";\n", powerShell.Streams.Error));
                }

                var sortedSyntaxItems = syntaxDetailses.ToList();
                sortedSyntaxItems.Sort((si1, si2) => String.CompareOrdinal(GetParameterSetNameFromSyntaxItem(si1), GetParameterSetNameFromSyntaxItem(si2)));

                foreach (var syntaxDetails in sortedSyntaxItems)
                {
                    MamlSyntax syntax = new MamlSyntax();

                    var syntaxParams = (object[])syntaxDetails.Properties["parameter"].Value;
                    foreach (PSObject syntaxParamPsObject in syntaxParams.OfType<PSObject>())
                    {
                        string paramName = UndoShiftName((string) syntaxParamPsObject.Properties["name"].Value);
                        MamlParameter parametersParameter = command.Parameters.FirstOrDefault(p => string.Equals(p.Name, paramName));
                        if (parametersParameter == null)
                        {
                            throw new HelpSchemaException(command.Extent, "Cannot find corresponding parameter for syntax item " + paramName);
                        }

                        MamlParameter syntaxParameter = new MamlParameter()
                        {
                            Name = parametersParameter.Name,
                            Type = parametersParameter.Type
                        };

                        FillUpParameterFromPSObject(syntaxParameter, syntaxParamPsObject);
                        syntax.Parameters.Add(syntaxParameter);
                    }

                    command.Syntax.Add(syntax);
                }
            }
        }