Это в основном вопрос awk, но он касается обработки данных для Moodle Формат Gift, следовательно, теги.

Я хочу отформатировать html-код в вопросе («тестовое» действие Moodle), но мне нужно заменить <и> соответствующими сущностями, так как они будут интерпретироваться как «настоящий» html, а не распечатываться. Однако я хочу иметь возможность набирать вопрос с помощью обычного кода и постобработать файл перед его импортом в качестве подарка в Moodle.

Я думал, что awk будет идеальным инструментом для этого.

Скажем, у меня есть этот (недействительный) вопрос о Moodle / подарке:

::q1::[html]This is a question about HTML:
<pre>
<p>some text</p>
</pre>
and some tag:<code><img></code>
{T}

Мне нужен сценарий, который переводит это в правильный вопрос о подарке:

::q1::[html]This is a question about HTML:
<pre>
&lt;p&gt;some text&lt;/p&gt;
</pre>
and some tag:<code>&lt;img&gt;</code>
{T}

Ключевой момент: замените <и> на &lt; и &gt;, когда:

  1. внутри блока <pre> - </pre> (при условии, что эти теги находятся в одной строке)
  2. между <code> и </code> с произвольной строкой между ними.

По первой части я в порядке. У меня есть сценарий оболочки, вызывающий awk (на самом деле gawk).

awk -f process_src2gift.awk $1.src >$1.gift

С process_src2gift.awk:

BEGIN { print "// THIS IS A GENERATED FILE !" }
{
    if( $1=="<pre>" ) # opening a "code" block
    {
        code=1;
        print $0;
    }
    else
    {
        if( $1=="</pre>" ) # closing a "code" block
        {
            code=0;
            print $0;
        }
        else
        { # if "code block", replace < > by html entities
            if( code==1 )
            {
                gsub(">","\\&gt;");
                gsub("<","\\&lt;");
            }
            print $0;
        }
    }
}
END { print "// END" }

Однако я придерживаюсь второго требования.

Вопросов:

  1. Можно ли добавить в мой код сценария awk для обработки кода hmtl внутри тегов <code>? Любая идея ? Я думал об использовании sed, но не понимал, как это сделать.

  2. Может быть, awk не подходит для этого? Я открыт для любых предложений по другому (стандартному для Linux) инструменту.

1
kebs 1 Дек 2019 в 22:21
Любой намек на то, почему голосование против? Какой пункт я пропустил?
 – 
kebs
1 Дек 2019 в 23:37
1
Не голосовал против. «Они», вероятно, так и сделали, потому что обработка html внутри awk считается непростой задачей ;-). Обычно происходит то, что вы можете решить эту проблему, и поэтому вы продолжаете, пока не дойдете до проблемы, которая не основана на reg-ex и которую нельзя решить, не вставая на голову (в awk), И тогда вам нужно научиться html-осведомленные процессы в большой спешке. (Извините, я не могу рекомендовать сменный инструмент). Я не вижу причин, по которым вы не можете расширить код, необходимый для управления другим флагом var code2? выполнить ту же замену. Удачи.
 – 
shellter
2 Дек 2019 в 00:06
Спасибо за информацию. Я понимаю, что обработка html с помощью awk полна подводных камней, но это действительно «побочный» случай, а не обработка всей html-страницы.
 – 
kebs
2 Дек 2019 в 00:22

1 ответ

Лучший ответ

Отвечая на собственный вопрос.

Я нашел решение, выполнив двухэтапный процесс awk:

  • первый шаг, как описано в вопросе
  • второй шаг, определяя <code> или </code> как разделитель полей, используя регулярное выражение, и обрабатываем замену строки для второго аргумента ($ 2).

Файл оболочки становится:

echo "Step 1"
awk -f process_src2gift.awk $1.src >$1.tmp

echo "Step 2"
awk -f process_src2gift_2.awk $1.tmp >$1.gift

rm $1.tmp

И второй файл awk (process_src2gift_2.awk) будет:

BEGIN { FS="[<][/]?[c][o][d][e][>]"; }
{
    gsub(">","\\&gt;",$2);
    gsub("<","\\&lt;",$2);
    if( NF >= 3 )
        print $1 "<code>" $2 "</code>" $3
    else
        print $0
}

Конечно, есть ограничения:

  • нет атрибутов в теге <code>
  • только одна пара <code></code> в строке
  • наверное другие ...
1
kebs 2 Дек 2019 в 18:12