function editor_addArticle(e,args)
 {    console.log('addArticle') ;
      console.log(args.markerId) ;
      //const editor = this.$refs.editor.instance
      const root = editor.model.document.getRoot()
      const range = editor.model.createRangeIn(root)
      const selection = editor.model.createSelection(range)
      let doc = {
        root: true,
        children: editor.model.getSelectedContent(selection).toJSON()
      }
      let selection_JSON=JSON.stringify(editor.model.getSelectedContent(selection).toJSON()) ;
      console.log(editor.model.getSelectedContent(selection)) ;
      console.log(selection_JSON) ;

      function filter (root, article) {
        if (root.attributes && root.attributes.kbarticle === article) {
          return root
        }

        if (root.children && root.children.length) {
          const children = []
          for (let child of root.children) {
            child = filter(child, article)
            if (child) {
              children.push(child)
            }
          }
          if (children.length) {
            root.children = children
            return root
          }
        }
        return null
      }


      //console.log('search item by attr: '+'kbarticle:'+args.markerId) ;
      doc = filter(doc, 'kbarticle:'+args.markerId)
      console.log('doc: ',doc)

      function buildDocument (root, doc) {
        console.log('========= buildDocument IN ===========================') ;
        console.log('doc.name='+doc.name) ;
        console.log('doc.children lengnt='+doc.children.length) ;

        //console.log('buildDocument') ;
        //console.log({ root, doc }) ;
        for (const node of doc.children) {
          //console.log('************************') ;
          let el
          let list = null
          console.log('---------------------') ;
          console.log('node.name='+node.name) ;
          console.log('node.data='+node.data) ;

          if (node.name)
          {
            switch (node.name) {
              case 'heading1':
                el = document.createElement('h1')
                break
              case 'heading2':
                el = document.createElement('h2')
                break
              case 'heading3':
                el = document.createElement('h3')
                break
              case 'heading4':
                el = document.createElement('h4')
                break
              case 'paragraph':
                el = document.createElement('p')
                break
              case 'table':
                el = document.createElement('table')
                break
              case 'tableRow':
                el = document.createElement('tr')
                break
              case 'tableCell':
                el = document.createElement('td')
                break
              case 'listItem':
                if (!list) {
                  list = document.createElement('ul')
                  root.append(list)
                }
                el = document.createElement('li')
                break
              default:
                //el = document.createElement('span')
                console.log('undefined tag: '+node.name) ;

                send_ajax_request({cmd:'quiz/show_alert_message',text:'Неизвестный тег: '+node.name,color:'red'})
                return
            }

            console.log('el=',el) ;

            if (list) {
              list.append(el)
            //  buildDocument(el, node)
            }
            if (el && node.children && node.children.length) {
              root.append(el)
              buildDocument(el, node)
            }
          }


          //console.log('node.data='+node.data) ;
          if (node.data) {
            root.innerHTML += node.data
            //console.log('root.innerHTML='+node.data) ;
          }
        }


        //console.log('--------------------------+') ;
        console.log('========= buildDocument OUT ===========================') ;
      }

      const oldRoot = document.getElementById('root')
      const newRoot = document.createElement('div')
      newRoot.id = 'root'
      oldRoot.replaceWith(newRoot)

      buildDocument(newRoot, doc)

      console.log('ranges.toJSON') ;
      console.log(editor.model.markers.get('kbarticle:'+args.markerId+':1').getRange().toJSON())

     //console.log($j('div#root')[0]) ;


      //console.log('innerHTML='+$j('div#root')[0].innerHTML) ;
      //send_ajax_request({cmd:'quiz/known_create2',section_id:section_id,data_json:editor.getData(),selection:$j('div#root')[0].innerHTML,markerId:args.markerId}) ;
      send_ajax_request({   cmd:'quiz/known_create2',
                            section_id:section_id,
                            data_json:editor.getData(),
                            //data_doc:editor.getData(),
                            selection:$j('div#root')[0].innerHTML,
                            selection_JSON:selection_JSON,
                            markerId:args.markerId,
                            markerJSON:JSON.stringify(editor.model.markers.get('kbarticle:'+args.markerId+':1').getRange().toJSON())}
      )
     //console.log('editor.model.markers.get')
     //console.log(editor.model.markers.get('kbarticle:'+args.markerId+':1').getRange().toJSON()) ;
 }

function ConvertDivAttributes( editor )
{
    // Allow <div> elements in the model.
    editor.model.schema.register( 'span', {
        allowWhere: '$block',
        allowContentOf: '$root'
    } );

    // Allow <div> elements in the model to have all attributes.
    editor.model.schema.addAttributeCheck( context => {
        if ( context.endsWith( 'span' ) ) {
            return true;
        }
    } );

    // View-to-model converter converting a view <div> with all its attributes to the model.
    editor.conversion.for( 'upcast' ).elementToElement( {
        view: 'span',
        model: ( viewElement, modelWriter ) => {
            return modelWriter.createElement( 'span', viewElement.getAttributes() );
        }
    } );

    // Model-to-view converter for the <div> element (attributes are converted separately).
    editor.conversion.for( 'downcast' ).elementToElement( {
        model: 'span',
        view: 'span'
    } );

    // Model-to-view converter for <div> attributes.
    // Note that a lower-level, event-based API is used here.
    editor.conversion.for( 'downcast' ).add( dispatcher => {
        dispatcher.on( 'attribute', ( evt, data, conversionApi ) => {
            // Convert <div> attributes only.
            if ( data.item.name != 'span' ) {
                return;
            }

            const viewWriter = conversionApi.writer;
            const viewDiv = conversionApi.mapper.toViewElement( data.item );

            // In the model-to-view conversion we convert changes.
            // An attribute can be added or removed or changed.
            // The below code handles all 3 cases.
            if ( data.attributeNewValue ) {
                viewWriter.setAttribute( data.attributeKey, data.attributeNewValue, viewDiv );
            } else {
                viewWriter.removeAttribute( data.attributeKey, viewDiv );
            }
        } );
    } );
}
