2

I am using markdown format to represent content (articles, problem statements) on pages of my site. Now I want to add some pictures or drawings to text sometimes.

I think of using SVG element embedded into HTML instead of storing raster images. And markdown processes this all right (if svg is enclosed in div element).

However, SVG format itself is not as simple as markdown and I now wonder, whether there exists some markdown-like processor which can take the commands in some simple format like:

svg 200, 150
set-color black
set-fill none
rect 0, 0, 200, 150
set-color #C00
set-fill #F00
circle 100, 75, 50

and convert it to svg element. Does anybody encountered something of the kind?

I think that javascript and canvas will do also if there is such markdown-like processor for them...

4

1 に答える 1

7

Markdown から SVG へのパーサーは知りませんが、作成するのはそれほど難しくありません。

ここにフィドルのデモがあります: http://jsfiddle.net/m1erickson/aPg8a/

ここに画像の説明を入力

JavaScriptでSVG要素を作成する方法を知っているSvg「クラス」から始めます

(この Svg クラスのコードはさらに下にあります)

この Svg クラスは、これらの SVG タスクを実行する方法を知っています。

  • 親 html svg 要素を作成します ( new Svg )
  • svg 要素のサイズを設定します ( .setSvgWidthHeight )
  • 新しい SVG シェイプのデフォルトのストローク カラーを設定します ( .setColor )
  • 新しい SVG 形状 ( .setFill ) のデフォルトの塗りつぶし色を設定します。
  • rect オブジェクトを作成し、svg 要素 ( .rect ) に追加します。
  • 円オブジェクトを作成し、svg 要素 ( .circle ) に追加します。

まず、サンプル マークダウンを作成します。

(すべてのマークダウンが整形式で有効であると仮定します)

// svg 200, 150 
// set-color black 
// set-fill none 
// rect 0, 0, 200, 150
// set-color #C00 set-fill #F00 
// circle 100, 75, 50

// sample markdown text

var markdown="svg 200, 150\nset-color black\nset-fill none\nrect 0, 0, 200, 150\nset-color #C00\nset-fill #F00\ncircle 100, 75, 50\n"

次に、そのマークダウンを次のように解析します。

// create a new Svg object
// this object knows how to create SVG elements

var svg=new Svg();

// strip off trailing return, if present
if(markdown.slice(-1)=="\n"){
    markdown=markdown.slice(0,-1);
}

// split markdown into individual commands
var commands=markdown.split("\n");

最後に、Svg クラスを使用して、各マークアップ コマンドを関連する SVG に処理します。

// process each command in commands using the svg object

for(var i=0;i<commands.length;i++){
    processCommand(svg,commands[i]);
    console.log(commands[i]);
}


// this function takes a line of Markup and executes the associated Svg command


function processCommand(svg,commandline){

    // get command and remove command from commandline

    var command=(commandline.split(" ")[0]).toLowerCase();
    commandline=commandline.substr(commandline.indexOf(" ")+1).trim();

    // get args (assuming comma/space delimiters)

    var args=commandline.split(/[ ,]+/);

    // execute the command with svg

    switch(command){
        case "svg":
            svg.setSvgWidthHeight(args[0],args[1])
            break;
        case "set-color":
            svg.setColor(args[0])
            break;
        case "set-fill":
            svg.setFill(args[0])
            break;
        case "rect":
            svg.rect(args[0],args[1],args[2],args[3])
            break;
        case "circle":
            svg.circle(args[0],args[1],args[2])
            break;
        default:
            break;
    }

}

以下は、開始するための Svg「クラス」オブジェクトです。

var Svg = (function () {

    // constructor
    function Svg() {
        this.svgns="http://www.w3.org/2000/svg";
        this.xlink='http://www.w3.org/1999/xlink'
        this.nextId=1000;
        this.fill="gray";
        this.stroke="black";
        this.strokeWidth=2;
        this.width =1;
        this.height=1;
        this.svg=document.createElementNS(this.svgns,"svg");
        this.svg.setAttribute('width', this.width);
        this.svg.setAttribute('height', this.height);
        document.body.appendChild(this.svg);
    }
    //
    Svg.prototype.create = function(elementType,fill,stroke,strokeWidth,id){
        var e=document.createElementNS(this.svgns,elementType);
        e.setAttribute("id",id||this.nextId++);
        e.setAttribute("fill",fill||this.fill);
        e.setAttribute("stroke",stroke||this.stroke);
        e.setAttribute("stroke-width",strokeWidth||this.strokeWidth);
        this.svg.appendChild(e);
        return(e);
    }
    //
    Svg.prototype.setSvgWidthHeight = function(width,height){
        this.svg.setAttribute("width",width);
        this.svg.setAttribute("height",height);
        return(this);
    }
    //
    Svg.prototype.rect = function (x,y,width,height) {
        var e=this.create("rect");
        e.setAttribute("x",x);
        e.setAttribute("y",y);
        e.setAttribute("width",width);
        e.setAttribute("height",height);
        e.setAttribute("fill",this.fill);
        e.setAttribute("stroke",this.stroke);
        return(this);
    };
    //
    Svg.prototype.setFill = function(fillcolor){
        this.fill=fillcolor;
        return(this);
    }
    //
    Svg.prototype.setColor = function(strokecolor){
        this.stroke=strokecolor;
        return(this);
    }
    //
    Svg.prototype.circle = function (cx,cy,radius) {
        var e=this.create("circle");
        e.setAttribute("cx",cx);
        e.setAttribute("cy",cy);
        e.setAttribute("r",radius);
        e.setAttribute("fill",this.fill);
        e.setAttribute("stroke",this.stroke);
        return(this);
    };

    return Svg;
})();
于 2013-10-29T16:50:32.020 に答える