2015-04-21 2 views
3

Я знаю, как сделать замену строки из внутри текстового шаблона, что-то простое, какPowershell текст/html шаблоны, которые включают в себя петли

текстовый файл

Hello ${name} 

шикарно

[string] $name = "World" 
$template = Get-Content 'c:\temp\docs\template.txt' 
$expanded = $ExecutionContext.InvokeCommand.ExpandString($template) 
$expanded 

Ожидаемый результат

Hello World 

Это все хорошо, но что, если мне нужно что-то более продвинутое?

текстовый файл

<div>title</div> 
<ul> 
    $(${points} | % { $_ }) 
</ul> 

шикарно

[string[]]$points = "First Point", "Second Point" 
$template = Get-Content 'c:\temp\docs\template.txt' -force 
$expanded = Invoke-Expression $template 
$expanded 

выход ожидается

<div>title<div> 
<ul> 
    <li>First Point</li> 
    <li>Second Point</li> 
</ul> 

Что мне нужно сделать, чтобы CREA te шаблоны цикла внутри текстового файла?


EDIT:

здесь понятие я буду так далеко, как шаблон будет иметь дело.

<div class="container-fluid"> 
    <div class="page-header"> 
     <h1>${name}</h1> 
     <p class="lead">${synopsis}</p> 
    </div> 
    <div class="row"> 
     <div class="col-md-12"> 
      <h2> Syntax </h2> 
     </div> 
     <pre> 
<code>${syntax}</code> 
     </pre> 
    </div> 
    <div class="col-md-12"> 
     <h2> Detailed Description </h2> 
     <div>${description}</div> 
    </div> 
    {ifdef links} 
    <div class="col-md-12"> 
     <h2> Related Commands </h2> 
     <div>${links}</div> 
    </div> 
    {endif links} 
    {ifdef parameters} 
    <div class="col-md-12"> 
     <h2> Parameters </h2> 
     <table> 
      <tr> 
       <th>Name</th> 
       <th>Description</th> 
       <th>Required?</th> 
       <th>Pipeline Input</th> 
       <th>Default Value</th> 
      </tr> 
      <tr> 
       {foreach param in ${parameters}} 
       <td>$($param.Name)</td> 
       <td>$($param.Description)</td> 
       <td>$(param.Required)</td> 
       <td>$(param.PipelineInput)</td> 
       <td>$(param.DefaultValue)</td> 
       {endforeach} 
      </tr> 
     </table> 
    </div> 
    {endif parameters} 
    {ifdef notes} 
    <div class="col-md-12"> 
     <h2> Notes </h2> 
     <div>${notes}</div> 
    </div> 
    {endif notes} 
    {ifdef examples} 
    <div class="col-md-12"> 
     <h2> Examples </h2> 
     {foreach example in ${examples}} 
     <h3> Example </h3> 
     <pre>${example.code}</pre> 
     <div>${example.remarks}</div> 
     {endforeach} 
    </div> 
</div> 
+0

Вы бы восприняли это как обман, чтобы выполнить цикл в PowerShell, а затем вставить строку, используя простую замену, как в первом примере. Поскольку это будет работать со вторым примером – Matt

+0

Да, я рассматриваю это, и если это необходимо, но я * задница *, полагаю, что в шаблоне должен быть способ: S –

+0

Хорошее форматирование комментариев :) – Matt

ответ

1

Я действительно заинтересован в хорошем ответе на это, но я продолжу свое предложение в комментарии. Я уверен, что вы способны сделать это сами, но это может быть полезно для кого-то.

Если ваш файл содержал

<div>title</div> 
<ul> 
${list} 
</ul> 

Тогда мы могли бы сделать это, чтобы заполнить список

$list = ("First Point", "Second Point" | ForEach-Object{"`t<li>$_</li>"}) -join "`r`n" 
$template = Get-Content 'c:\temp\docs\template.txt' -raw 
$ExecutionContext.InvokeCommand.ExpandString($template) 

Да, я знаю, что это не совсем то, что вы просите, но у него есть такой же результат.

Почему бы вам не превратить весь файл в код?

Отказ от ответственности: Я хотел бы указать, что расширение строк и исполняемый код из файлов - это две разные вещи. Что делать, если кто-то помещает вредоносный код в ваш файл шаблона? Вы можете слепо выполнить его. Реалистичная проблема? Нет. Возможная катастрофа? Может быть.

Я обновляю небольшую часть вашего образца для подтверждения метода. Да, HTML некорректен и сосет. Он существует, чтобы показать, что я имею в виду.

Пример файла

'<div class="container-fluid">' 
' <div class="page-header">' 
"  <h1>$name</h1>" 
"  <p class=`"lead`">$synopsis</p>" 
' </div>' 
' <tr>' 
foreach($param in $parameters){ 
"  <td>$($param.Name)</td>" 
"  <td>$($param.Description)</td>" 
} 
' </tr>' 

Я выбрал этот фрагмент кода, так как вы видите простую переменную, простую переменную в кавычки и структуру цикла. У меня есть одинарные кавычки в большинстве строк, так как они будут просто отправлены как стандартный вывод строки. Итак, с этим, мы используем следующий код:

$name = "Matt" 
$synopsis ="Ughhh... stuff" 
$parameters = 1,2 | Foreach-object{[pscustomobject]@{Name="$_ Factory";Description="$_ Apples"}} 

$template = Get-Content 'c:\temp\docs\template.txt' -raw 
Invoke-Expression $template 

Какие Сетки следующее, снова ужасный, выход.

<div class="container-fluid"> 
    <div class="page-header"> 
     <h1>Matt</h1> 
     <p class="lead">Ughhh... stuff</p> 
    </div> 
    <tr> 
     <td>1 Factory</td> 
     <td>1 Apples</td> 
     <td>2 Factory</td> 
     <td>2 Apples</td> 
    </tr> 
+0

Это будет работать, я думаю. Гораздо чище, чем я сейчас работаю. –

+0

@ChaseFlorell хорошо, если ничего другого не появляется, по крайней мере, это может сработать. Мета-программирование - это весело! – Matt

+0

Спасибо за направление @Matt, я поделился своим окончательным решением в [моем блоге] (https://chaseflorell.github.io/powershell/2015/04/27/how-to-generate-beautiful-powershell-documentation /) –

Смежные вопросы