Drafts Action Directory

CSV To Markdown Table

Posted by martinpacker, Last update 8 days ago

Select the text - in CSV format - and this action will prompt you whether you want the first row treated as a heading row or not. Then it will replace this text with the Markdown table equivalent. Enhanced to guess cell alignments.

Install

Steps

  • script

    function parse_CSV(csv_string){
      rows=[]
      row=[]
    
      in_string=false
      cell_value=""
        
      for(ch of csv_string){
        if(ch==','){
          // Might be a cell separator
          if(in_string==false){
            // Is cell separator
            row.push(cell_value)
            cell_value=""
          }else{
            // In a cell and not a separator
            cell_value+=ch
          }
        }else if(ch=='\n' && in_string==false){
          // New row
          if(cell_value!=''){
            // Existing cell to add to row
            row.push(cell_value)
            cell_value=""
          }
          rows.push(row)
          row=[]
        }else if(ch=='"'){
          // String start or end
          if(in_string==false) {
            // String start
            in_string=true
          }else{
            // String end
            in_string=false
            row.push(cell_value)
            cell_value=""
          }
        }else{
          // normal character
          cell_value+=ch
        }
      }
      
      if(cell_value!=""){
        row.push(cell_value)
      }
      
      if(row.length>0){
        rows.push(row)
      }
    
      return rows
    }
    
    // Work out what the column types are
    //
    // L = Left alignment
    // R = Right alignment
    //
    function get_column_types(cellArray){
      col_has_numeric=[]
      col_has_nonnumeric=[]
      col_count=0
    
      // Figure out how many columns we have
      for(row of cellArray){
        col_count=Math.max(col_count,row.length)
      }
      
      // Prime column detected types array
      for(i=0;i<col_count;i++){
        col_has_numeric.push(0)
        col_has_nonnumeric.push(0)
      }
    
      // Loop through rows to figure out type of each cell
      for(row of cellArray){
        row_length=row.length
        for(i=0;i<row_length;i++){
          if(isNaN(row[i])){
            col_has_nonnumeric[i]++
          }else{
            col_has_numeric[i]++
          }
        }
      }
      
      alignments=[]
      for(i=0;i<col_count;i++){
        if(col_has_nonnumeric[i]>0){
          alignments.push("L")
        }else{
          alignments.push("R")
        }
      }
      return alignments
      
    }
    
    // Format a one-dimensional array of text cells as a line with newline
    function format_row(cells){
      rowText="|"
      for(cell of cells){
        rowText+=cell+"|"
      }
      return rowText+"\n"
    }
    
    // Extract the selected text and parse into an array of rows
    csv=editor.getSelectedText()
    rows=parse_CSV(csv)
    rowCount=rows.length
    
    // Prepare a dialog to control Markdown table generation
    p=Prompt.create()
    p.title="Control Markdown Table Creation"
    p.addSwitch("heading","First row is heading",true)
    p.addButton("OK")
    
    // Display this dialog
    p.show()
    
    // If not cancelled then handle result of the dialog
    if(p.buttonPressed=="OK"){
    
      // Glean column alignments as an array
      alignments=get_column_types(rows)
    
      // Format alignment row
      alignmentRow="|"
        
      for(a of alignments){
        if(a=="L"){
          alignmentRow+=":-|"
        }else{
          alignmentRow+="-:|"
        }
       }
    
      if(p.fieldValues["heading"]==false){
        // Text starts with empty header
        replacementText="||\n"+alignmentRow+"\n"
        
        // Add the rows
        for(row of rows){
          replacementText+=format_row(row)
        }
      }else{
        // Calculate number of cells in longest row
        columns=0
        for(row of rows){
          columns=Math.max(columns,row.length)
        }
    
       // Replacement text starts with the first row
        replacementText=format_row(rows[0])
        
        // Now add alignment row
        replacementText+=alignmentRow+"\n"
       
        // Now add the rest of the rows
        for(row=1;row<rowCount;row++){
          replacementText+=format_row(rows[row])
        }
      }
      
      // Replace the selected text with the Markdown table version
      if(replacementText!=""){
        editor.setSelectedText(replacementText)
      }
    }

Options

  • After Success Default
    Notification Info
    Log Level Info

Comments

Actions available in the Action Directory are uploaded by community members. Use appropriate caution reviewing downloaded actions before use.