Estou tentando converter a marcação Pandoc em marcação wiki do Confluence, estou usandomarkdown2confluênciapara fazer a maior parte do trabalho. Isso funciona muito bem, exceto quando estou falando sobre CSS e FreeMarker que usam {
& }
no código enquanto o Confluence usa {{
& }}
para marcar o início/fim do bloco de código. Portanto, preciso corresponder a um padrão incluído em {{...}}
.
Se eu conhecesse (mais) Ruby, poderia consertá-lo lá, mas sou um cara da velha escola do Unix, então pensei em awk ou sed.
Então cheguei até:
sed 's/{{\([^}}]*\)}}/{{"\1"}}/g' tmp.wkd
que leva:
First we need a way to select a state (or group of states) CSS uses what
is called a selector to choose which elements to apply to, we have been
using one up until now without noticing, it is the {{*}} at the beginning
of our CSS. This is a special selector that means select everything. So
the rule that follows it (the bit between {{{}} and {{}}} apply to every
polygon on the map. But CSS allows us to insert a filter instead by
using {{[...]}} instead of {{*}}.
e produz:
First we need a way to select a state (or group of states) CSS uses what
is called a selector to choose which elements to apply to, we have been
using one up until now without noticing, it is the {{"*"}} at the beginning
of our CSS. This is a special selector that means select everything. So
the rule that follows it (the bit between {{"{"}} and {{""}}} apply to every
polygon on the map. But CSS allows us to insert a filter instead by
using {{"[...]"}} instead of {{"*"}}.
Mas o que eu preciso é:
First we need a way to select a state (or group of states) CSS uses what
is called a selector to choose which elements to apply to, we have been
using one up until now without noticing, it is the {{*}} at the beginning
of our CSS. This is a special selector that means select everything. So
the rule that follows it (the bit between {{\{}} and {{\}}} apply to every
polygon on the map. But CSS allows us to insert a filter instead by
using {{[...]}} instead of {{*}}.
Também precisa lidar com {{${type.name}}}
o que deve se tornar {{$\{type.name\}}}
.
Existem dois problemas
- Preciso substituir
{
por\{
em vez de usar aspas, então preciso modificar\1
de alguma forma. - A aparência desagradável
{{}}}
(que deveria acontecer{{\}}}
não sai bem, não importa o quanto eu tente encerrar a correspondência de padrões.
Responder1
O seguinte comando sed parece funcionar:
sed 's/{{\([^*[a-z][^}]*\)}}/{{\\\1}}/g;s/{{\\${\([^}]*\)}}}/{{$\\{\1\\}}}/g'
Explicação:
{{\([^*[a-z][^}]*\)}}
finds{{stuff}}
, exceto quandostuff
começa com*
ou[
ou uma letra minúscula.- Substitua por
{{\stuff}}
. - Então
{{\\${\([^}]*\)}}}
encontra{{\${junk}}}
. - E substitui por
{{$\{junk\}}}
.
Editar: Uma solução alternativa, após esclarecimento do OP, poderia ser esta:
sed 's/\({{[^}]*\){\([^}]*}}\)/\1\\{\2/g;s/\({{[^}]*\)}}}/\1\\}}}/g'
Como todos sabemos, o sed não pode fazer análise recursiva, mas isso deve funcionar na maioria dos casos simples.
Explicação:
\({{[^}]*\){\([^}]*}}\)
encontra{{foo{bar}}
, ondefoo
ebar
não contém}
.- E substitui por
{{foo\{bar}}
. (A nota{{xxx{yyy}}}
foi tratada corretamente.) - Então
\({{[^}]*\)}}}
encontra{{baz}}}
, ondebaz
não contém}
. - E substitui por
{{baz\}}}
.
foo
, bar
, e baz
podem estar vazios, por exemplo, {{}}}
são convertidos em {{\}}}
, conforme necessário.