Техническая часть:GraphViz улучшенный — исходники

Материал из WEBI

Перейти к: навигация, поиск

Про классический GraphViz, его установку и использование сказано в статье Техническая часть:GraphViz. Тут приведены наши изменения этого модуля и комментарии к ним.

Содержание

Русский GraphViz

Версия 1.1

  • Немного причесан код.
  • Изменена схема генерации URI на более короткие.

Версия 1.0

  • Создание картинки в svg и последующей конвертации ее в png.

Установка

Все требования должны быть удовлетворены до начала установки. Вы должны создать Graphviz*.php в директорию $mediawiki/extensions. Скопируйте в него приведенный ниже код с необходимыми изменениями. Задайте согласно настройкам вашей системы и устновкам

  • $wgGraphVizSettings->dotCommand = "/usr/bin/dot"
  • $wgGraphVizSettings->convertCommand = "java -jar /usr/bin/batik-rasterizer.jar"

Здесь параметры даны исключительно для примера

Код

Требует чтобы были установлены:

  • Установленный интерпретатор dot.
    О том как это сделать на Unix (в худшем случае): Сборка Graphviz
  • Установленный конвертер из svg в png.
    Про работу с svg подробно сказано тут Manual:Image Administration/ru.
    Мы используем Батик.


<?php

# Для использования, включите этот файл в LocalSettings.php

class GraphVizSettings {
    /**
    * Настройки GraphViz
    */
    var $dotCommand;
    var $folder;
    var $convertCommand;
};

$wgGraphVizSettings = new GraphVizSettings;
/*
    Значения по умолчанию :
*/
$wgGraphVizSettings->dotCommand = "/usr/bin/dot";
$wgGraphVizSettings->folder = "graphviz";
$wgGraphVizSettings->convertCommand = "/usr/bin/rasterizer";


$wgExtensionFunctions[] = "wfGraphVizExtension";
    # добавим элемент к функциям расширения

function wfGraphVizExtension() {
    /**
    * Инициализирует расширение.
    */

    global $wgParser;
    $wgParser->setHook( "graphviz", "renderGraphviz" );
}

function renderGraphviz( $dotcode,  $params = array(), $parser)
{
    /**
    * Обрабатывает и отображает GraphViz код
    */

    /*Используем из глобального пространства имен*/
    global $IP;
    global $wgUploadDirectory;
    global $wgUploadPath;
    global $wgGraphVizSettings;
    global $wgArticlePath;
    global $wgTmpDirectory;


    $numHash = md5( $dotcode, true );

    $fullHash = base64_encode($numHash);
    $fullHash = str_replace("=","",  $fullHash);
    $fullHash = str_replace("/","_", $fullHash);
    $fullHash = str_replace("+","-", $fullHash);

    $folder = $wgGraphVizSettings->folder
    .'/'. substr($fullHash, 0, 1)
    .'/'. substr($fullHash, 1, 1)
    .'/'. substr($fullHash, 2, 1);

    $hash = substr($fullHash, 3);

    $dest = "{$wgUploadDirectory}/{$folder}/";

    # получим путь к папке к файлу

    if ( ! is_dir( $dest ) ) {
        # если нет папки ~~./graphviz создадим ее
        mkdir( $dest, 0777, true );
    }

    if ( ! is_dir( $wgTmpDirectory ) ) {
        # если нет папки ~~./tmp создадим ее
        mkdir( $wgTmpDirectory, 0777, true);
    }

    $dotName = $hash.'.'.'dot';
    $pngName = $hash.'.'.'png';
    $svgName = $hash.'.'.'svg';
    $mapName = $hash.'.'.'map';
    $errName = $hash.'.'.'err';

    $fullDotName = $dest.$dotName;
    $fullPngName = $dest.$pngName;
    $fullSvgName = $dest.$svgName;
    $fullMapName = $dest.$mapName;
    $fullErrName = $dest.$errName;

    $pngUrl = "{$wgUploadPath}/{$folder}/{$pngName}";
    $svgUrl = "{$wgUploadPath}/{$folder}/{$svgName}";

    if ( ! (
        (
            file_exists( $fullPngName )
            &&  file_exists( $fullSvgName )
        )
        || file_exists( $fullErrName )
    ))
    {
        $handle = fopen($fullDotName, "w");
        fwrite($handle, $dotcode);
        fclose($handle);
            # открыли файл, записали dot-код, pfrhskb файл.

        /* формируем строки для выполнения в shell */
        $cmdline_dot = wfEscapeShellArg( $wgGraphVizSettings->dotCommand) .
            " -Tsvg -o " .
            wfEscapeShellArg($fullSvgName) .
            " " .
            wfEscapeShellArg($fullDotName) ;

        $cmdline_convert =  $wgGraphVizSettings->convertCommand .
            " ".
            wfEscapeShellArg($fullSvgName);

        $cmdline_dot_map = wfEscapeShellArg( $wgGraphVizSettings->dotCommand) .
            " -Tcmapx -o " .
            wfEscapeShellArg($fullMapName) .
            " " .
            wfEscapeShellArg($fullDotName) ;

        /* выполняем строки выше в shell */
        $returned_dot = exec ($cmdline_dot);
        $returned_convert = exec ($cmdline_convert);
        $returned_dot_map = exec ($cmdline_dot_map);

        unlink($fullDotName);
        # удалим файл и исходным текстом
    }

    @$err=file_get_contents($fullErrName);

    if ( $err != "" ) {
        /*
            Если есть ошибка
        */
        $txt = "<div id=\"toc\"><tt>$err</tt></div>";
    } else {
        /*
            Если все ок
        */
        @$map = file_get_contents($fullMapName);
        $map=preg_replace("#<ma(.*)>#"," ",$map);
        $map=str_replace("</map>","",$map);

        $title = "";
        if (isset($params['title'])) {
            $title = $params['title'];
            $_title = "title=\"{$title}\"";
        }

        $alt = str_replace("\n","", htmlspecialchars (strip_tags ( $dotcode)));
        $_alt = "alt=\"{$alt}\"";
        if (isset($params['alt'])) {
            $alt = $params['alt'];
            $_alt = "alt=\"{$alt}\"";
        }

        $_title = str_replace("\n","", htmlspecialchars (strip_tags ( $_title)));
        $_alt = str_replace("\n","", htmlspecialchars (strip_tags ( $_alt)));

        $txt  = #$cmdline_convert .
                #"<br />".
                #$returned_convert.
                #"<br />".
                "<map name=\"{$fullHash}\">{$map}</map> " .
                "<img src=\"{$pngUrl}\" {$_alt} {$_title} />" .
                " <a href=\"{$svgUrl}\" >[svg]</a>";

    }
    return $txt;
}
?>
Личные инструменты