Call Kramdown with Ruby on Android

This is the first blog. The example shows how to use kramdown to convert markdown file to html on android platform.

Introduction

Normally, jekyll uses kramdown to parse the markdown file. kramdown can convert markdown file to html which is written in pure ruby.

The example shows how to use kramdown to convert markdown file to html.

Background

This example is based on CLE. CLE supports android platform, ruby language, and interaction between ruby and java.

1. Create project and Add the dependent files

  • add starcore_android_rX.XX.jar and share libraries

  • pack ruby libraries to zip file

In this sample, ruby 2.2 is used.

  • pack kramdown-1.16.2 to zip file

  • add files to project folder assets

2. Public function, Extract the zip file to the application’s installation directory

  • copyFile
    private void copyFile(Activity c, String Name,String desPath) throws IOException {
        File outfile = null;
        if( desPath != null )
            outfile = new File("/data/data/"+getPackageName()+"/files/"+desPath+Name);
        else
            outfile = new File("/data/data/"+getPackageName()+"/files/"+Name);
        //if (!outfile.exists()) {
        {
            outfile.createNewFile();
            FileOutputStream out = new FileOutputStream(outfile);
            byte[] buffer = new byte[1024];
            InputStream in;
            int readLen = 0;
            if( desPath != null )
                in = c.getAssets().open(desPath+Name);
            else
                in = c.getAssets().open(Name);
            while((readLen = in.read(buffer)) != -1){
                out.write(buffer, 0, readLen);
            }
            out.flush();
            in.close();
            out.close();
        }
    }
  • unzip
private static boolean CreatePath(String Path){
        File destCardDir = new File(Path);
        if(!destCardDir.exists()){
            int Index = Path.lastIndexOf(File.separator.charAt(0));
            if( Index < 0 ){
                if( destCardDir.mkdirs() == false )
                    return false;
            }else{
                String ParentPath = Path.substring(0, Index);
                if( CreatePath(ParentPath) == false )
                    return false;
                if( destCardDir.mkdirs() == false )
                    return false;
            }
        }
        return true;
    }

    private static boolean unzip(InputStream zipFileName, String outputDirectory,Boolean OverWriteFlag ) {
        try {
            ZipInputStream in = new ZipInputStream(zipFileName);
            ZipEntry entry = in.getNextEntry();
            byte[] buffer = new byte[1024];
            while (entry != null) {
                File file = new File(outputDirectory);
                file.mkdir();
                if (entry.isDirectory()) {
                    String name = entry.getName();
                    name = name.substring(0, name.length() - 1);
                    if( CreatePath(outputDirectory + File.separator + name) == false )
                        return false;
                } else {
                    String name = outputDirectory + File.separator + entry.getName();
                    int Index = name.lastIndexOf(File.separator.charAt(0));
                    if( Index < 0 ){
                        file = new File(outputDirectory + File.separator + entry.getName());
                    }else{
                        String ParentPath = name.substring(0, Index);
                        if( CreatePath(ParentPath) == false )
                            return false;
                        file = new File(outputDirectory + File.separator + entry.getName());
                    }
                    if( !file.exists() || OverWriteFlag == true){
                        file.createNewFile();
                        FileOutputStream out = new FileOutputStream(file);
                        int readLen = 0;
                        while((readLen = in.read(buffer)) != -1){
                            out.write(buffer, 0, readLen);
                        }
                        out.close();
                    }
                }
                entry = in.getNextEntry();
            }
            in.close();
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

Using the code

1. Unzip the file to app folder

        File destDir = new File("/data/data/"+getPackageName()+"/files");
        if(!destDir.exists())
            destDir.mkdirs();
        final String nativeLibraryDir = this.getApplicationInfo().nativeLibraryDir;
        try{
            AssetManager assetManager = getAssets();
            InputStream dataSource = null;
            dataSource = assetManager.open("ruby-2.2.zip");
            unzip(dataSource, "/data/data/"+getPackageName()+"/files",false );
            dataSource.close();

            dataSource = assetManager.open("kramdown-1.16.2.zip");
            unzip(dataSource, "/data/data/"+getPackageName()+"/files",false );
            dataSource.close();
        }
        catch(Exception e)
        {

        }

2. Initilize CLE

        /*----init starcore----*/
        StarCoreFactoryPath.StarCoreCoreLibraryPath = this.getApplicationInfo().nativeLibraryDir;
        StarCoreFactoryPath.StarCoreShareLibraryPath = this.getApplicationInfo().nativeLibraryDir;
        StarCoreFactoryPath.StarCoreOperationPath = "/data/data/"+getPackageName()+"/files";

        final StarCoreFactory starcore= StarCoreFactory.GetFactory();
        StarServiceClass Service=starcore._InitSimple("test","123",0,0);
        SrvGroup = (StarSrvGroupClass)Service._Get("_ServiceGroup");
        Service._CheckPassword(false);

        starcore._RegMsgCallBack_P(new StarMsgCallBackInterface(){
            public Object Invoke(int ServiceGroupID, int uMes, Object wParam, Object lParam){
                if (uMes == starcore._Getint("MSG_DISPMSG") || uMes == starcore._Getint("MSG_DISPLUAMSG") ||
                        uMes == starcore._Getint("MSG_VSDISPMSG") || uMes == starcore._Getint("MSG_VSDISPLUAMSG"))
                {
                    String Str;
                    Str = (String)wParam;
                    System.out.println(Str);
                }
                return null;
            }
        });

2. Initilize ruby

        try{
            System.load(this.getApplicationInfo().nativeLibraryDir+"/libruby.so");
        }
        catch(UnsatisfiedLinkError ex)
        {
            System.out.println(ex.toString());
        }
        SrvGroup._InitRaw("ruby",Service);
        StarObjectClass ruby = Service._ImportRawContext("ruby","",false,"");
        System.out.println(ruby._Get("LOAD_PATH"));
        System.out.println(ruby._Get("File"));

3. Set ruby libraries searching path

        StarObjectClass LOAD_PATH = (StarObjectClass)ruby._R("LOAD_PATH");

        LOAD_PATH._Call("unshift", "/data/data/"+getPackageName()+"/files/lib/ruby/2.2.0");
        LOAD_PATH._Call("unshift", "/data/data/"+getPackageName()+"/files/armeabi-v7a/lib-dynload");
        LOAD_PATH._Call("unshift", "/data/data/"+getPackageName()+"/files");
        LOAD_PATH._Call("unshift", "/data/data/"+getPackageName()+"/files/kramdown-1.16.2/lib");

4. Call kramdown

        ruby._Call("require","enc/encdb");  //--else, will encoding error
        ruby._Call("require","kramdown");
        StarObjectClass KramdownDocument = (StarObjectClass)ruby._Call("eval","Kramdown::Document");
        StarObjectClass resobj = KramdownDocument._New("","","# aaaaaa");
        Object res = resobj._Call("method_missing","to_html");     

Sample Download

call_markdown_with_ruby_on_android.zip

History