Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added restructuredtext support #12

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Copy Excel Paste Markdown

You can clone the repo and then point your browser to the cloned `index.html`.

Copy a table in Excel (or other spreadsheet programs) and paste it as a Markdown table.

![demo](https://cl.ly/120h1K2Q1Y3H/Screen%20Recording%202016-08-31%20at%2010.31%20PM.gif)
Expand All @@ -12,13 +14,14 @@ You can optionally specify column alignment information by prepending one of the
* ^r - right alignment
* ^l - left alignment (the default)

For example: enter the following in Excel to right-align the second column and center-align the third column:
For example: enter the following csv in Excel to right-align the second column and center-align the third column:

| animal | ^rweight | ^ccolor |
|--------|----------|----------|
| dog | 30lb | tan |
| dog | 85lb | black |
| cat | 18lb | calico |
```
animal,^rweight,^ccolor
dog,30lb,tan
dog,85lb,black
cat,18lb,calico
```

This will produce the following markdown table when pasted:

Expand All @@ -30,7 +33,33 @@ This will produce the following markdown table when pasted:
| cat | 18lb | calico |
```

## Contributors
and the output table with thus look like

| animal | weight | color |
|--------|-------:|:------:|
| dog | 30lb | tan |
| dog | 85lb | black |
| cat | 18lb | calico |

## Added features for reStructured Text

Another simple markup language is [reStructuredText](https://docutils.sourceforge.io/rst.html). The `index.html` now contains three extra text areas for the three table variants that exist in reST.

reST has three options for creating tables.

- List tables. These are ideal for tables where you want to fold the text.
- Simple tables. This is a bit of a misnomer: these are most like markdown tables
- Multicell or grid tables. These are similar to markdown as well.

Note that reStructuredText does not support the alignment of cells. Hence the alignment is ignored.

You can find more information [here](https://docutils.sourceforge.io/docs/user/rst/quickref.html).

## Simple Mocha tests

If you have [mocha](https://mochajs.org/) installed you can run the tests in the test directory.

# Contributors

- @jonmagic
- [@thisdavej](https://github.com/thisdavej)
Expand Down
221 changes: 221 additions & 0 deletions conversion_functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
function columnWidth(rows, columnIndex) {
return Math.max.apply(null, rows.map(function(row) {
return row[columnIndex].length
}))
}

function split_to_rows(data) {
return data.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(function(row) {
row = row.replace('\n', ' ')
return row.split("\t")
})
}

function convert_to_md(data) {
var rows=split_to_rows(data)
var colAlignments = []
var columnWidths = rows[0].map(function(column, columnIndex) {
var alignment = "l"
var re = /^(\^[lcr])/i
var m = column.match(re)
if (m) {
var align = m[1][1].toLowerCase()
if (align === "c") {
alignment = "c"
} else if (align === "r") {
alignment = "r"
}
}
colAlignments.push(alignment)
column = column.replace(re, "")
rows[0][columnIndex] = column
return columnWidth(rows, columnIndex)
})
var markdownRows = rows.map(function(row, rowIndex) {
// | Name | Title | Email Address |
// |--------------|-------|----------------|
// | Jane Atler | CEO | [email protected] |
// | John Doherty | CTO | [email protected] |
// | Sally Smith | CFO | [email protected] |
return "| " + row.map(function(column, index) {
return column + Array(columnWidths[index] - column.length + 1).join(" ")
}).join(" | ") + " |"
row.map

})
markdownRows.splice(1, 0, "|" + columnWidths.map(function(width, index) {
var prefix = ""
var postfix = ""
var adjust = 0
var alignment = colAlignments[index]
if (alignment === "r") {
postfix = ":"
adjust = 1
} else if (alignment == "c") {
prefix = ":"
postfix = ":"
adjust = 2
}
return prefix + Array(columnWidths[index] + 3 - adjust).join("-") + postfix
}).join("|") + "|")

return markdownRows.join("\n")
}

function convert_to_listtable(data) {
var rows=split_to_rows(data)
// remove the unwanted characters that have no effect in restructured text
var firstRow=rows[0].map(function(column,columnIndex){
var re = /^(\^[lcr])/i
return(column.replace(re, ""))
})
rows[0]=firstRow
// Run through it row by row and for each row column by column
// The first column has a different indent
// Each cell has its own line
var rstListTableRows = rows.map(function(row, rowIndex) {
return row.map(function(column, index) {
var indentString = ( index > 0 ) ? "\t - " : "\t* - "
return indentString + column
}).join("\n")
})

var columnWidths = ""
if(rows[0].length>1) {
var columnWidth = Math.floor(100 / rows[0].length)
var firstColumnWidth = 100 - columnWidth*(rows[0].length-1)
columnWidths = rows[0].map(function(column,index) {
return "" + ( index > 0 ) ? columnWidth : firstColumnWidth
}).join(" ")
} else {
columnWidths = "" + 100
}
return ".. list-table:: Title"+"\n" + "\t:widths: " + columnWidths + "\n" + "\t:header-rows: 1" + "\n\n" + rstListTableRows.join("\n")
}

function convert_to_variant1(data) {
var rows=split_to_rows(data)
var firstRow=rows[0].map(function(column,columnIndex){
var re = /^(\^[lcr])/i
return(column.replace(re, ""))
})
rows[0]=firstRow
var columnWidths = rows[0].map(function(column, columnIndex) {
return columnWidth(rows, columnIndex)
})
var indentString = "\t"
// Get the table
// Run through it row by row and for each row column by column
// The first column has a different indent
// Each cell has its own line
// The indent is based on 4 spaces, which seems to be quite standard in python
// +======+=====+========+==========+
// | naam | int | letter | fraction |
// +======+=====+========+==========+
// | aap | 1 | a | 0.333333 |
// +------+-----+--------+----------+
// | noot | 2 | b | 0.250000 |
// +------+-----+--------+----------+
// | mies | 3 | c | 0.200000 |
// +======+=====+========+==========+
var rstTableRows = rows.map(function(row, rowIndex) {
return "| " + row.map(function(column, index) {
return column + Array(columnWidths[index] - column.length + 1).join(" ")
}).join(" | ") + " |"
})

var lenSize = rstTableRows.length
if(lenSize>1) {
rstTableRows.splice(1, 0, "+" + columnWidths.map(function(width, index) {
return Array(columnWidths[index] + 3).join("=")
}).join("+") + "+")
} else {
// if there is only one row, then is the last one
rstTableRows.splice(1, 0, "+" + columnWidths.map(function(width, index) {
return Array(columnWidths[index] + 3).join("-")
}).join("+") + "+")
}
rstTableRows.splice(0, 0, "+" + columnWidths.map(function(width, index) {
return Array(columnWidths[index] + 3).join("-")
}).join("+") + "+")

lenSize = rstTableRows.length

if( lenSize > 3 ) {
// the last row
rstTableRows.splice(lenSize, 0, "+" + columnWidths.map(function(width, index) {
return Array(columnWidths[index] + 3).join("-")
}).join("+") + "+")
// Now we need to look whether we have more than 5, if so then we need to do the
// normal table inserts
lenSize = rstTableRows.length
if(lenSize > 5) {
var lastRow = lenSize - 1
for(i=lastRow-1;i>3;i=i-1) {
rstTableRows.splice(i, 0, "+" + columnWidths.map(function(width, index) {
return Array(columnWidths[index] + 3).join("-")
}).join("+") + "+")
}
}
}
// https://www.w3.org/TR/clipboard-apis/#the-paste-action
// When pasting, the drag data store mode flag is read-only, hence calling
// setData() from a paste event handler will not modify the data that is
// inserted, and not modify the data on the clipboard.
// In other words, we cannot already reset the clipboard from here, leaving it to the user to manually copy
// the text in the text area
// Some say this need the htmlonly directive ... but rst2html does not know about it
return rstTableRows.map(function(row,rowIndex) { return indentString + row }).join("\n")
}

function convert_to_variant2(data) {
var rows=split_to_rows(data)
var firstRow=rows[0].map(function(column,columnIndex){
var re = /^(\^[lcr])/i
return(column.replace(re, ""))
})
rows[0]=firstRow
var columnWidths = rows[0].map(function(column, columnIndex) {
return columnWidth(rows, columnIndex)
})
var indentString = "\t"
// Run through it row by row and for each row column by column
// The first column has a different indent
// Each cell has its own line
// The indent is based on 4 spaces, which seems to be quite standard in python
// .. htmlonly::
//
var rstTableRows = rows.map(function(row, rowIndex) {
return row.map(function(column, index) {
if( columnWidths[index]-column.length +1 > 0 ) {
return column + Array(columnWidths[index] - column.length + 1 ).join(" ")
} else {
return column
}
}).join(" ")
})
// x
// underline open
rstTableRows.splice(1, 0, columnWidths.map(function(width, index) {
return Array(columnWidths[index]+1).join("=")
}).join(" ") )
// first
rstTableRows.splice(0, 0, columnWidths.map(function(width, index) {
return Array(columnWidths[index] +1).join("=")
}).join(" ") )
var lenSize = rstTableRows.length
if( lenSize > 3 ) {
rstTableRows.splice(lenSize, 0, columnWidths.map(function(width, index) {
return Array(columnWidths[index] +1).join("=")
}).join(" ") )
}
return rstTableRows.map(function(row,rowIndex) { return indentString + row }).join("\n")
}

// the below line adds nothing, it just serves to make the mocha testing work
// from the directory this file is in simply run `mocha` (if you have it installed)
// to perform the tests
exports.convert_to_md=convert_to_md;
exports.convert_to_listtable=convert_to_listtable;
exports.convert_to_variant1=convert_to_variant1;
exports.convert_to_variant2=convert_to_variant2;
82 changes: 77 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>Copy Excel Paste Markdown</title>

<title>Copy Excel Paste Markdown/Restructured Text</title>
<style>
textarea {
width: 400px;
Expand All @@ -13,9 +12,82 @@
}
</style>
</head>

<body>
<textarea id="editor"></textarea>
<script src="script.js"></script>
<p>
<input type="button" value="Clear all" onclick="javascript:eraseText();">
</p>
<table style="width:100%">
<tr>
<td>
<h4>Markdown</h4>
<input type="button" value="Copy" onclick="javascript:copy_markdown();">
</td>
<td>
<h4>RST Listtable</h4>
<input type="button" value="Copy" onclick="javascript:copy_rst_listtable();">
</td>
</tr>
<tr>
<td>
<textarea id="editor_markdown"></textarea>
</td>
<td>
<textarea id="editor_rst_listtable"></textarea>
</td>
</tr>
<tr>
<td>
<h4> RST table variant 1</h4>
<input type="button" value="Copy" onclick="javascript:copy_rst_variant1();">
</td>
<td>
<h4> RST table variant 2</h4>
<input type="button" value="Copy" onclick="javascript:copy_rst_variant2();">
</td>
</tr>
<tr>
<td>
<textarea id="editor_rst_variant1"></textarea>
</td>
<td>
<textarea id="editor_rst_variant2"></textarea>
</td>
</tr>
</table>
<script type="text/javascript">
function looksLikeTable(data) {
// this should still be implemented ?
// How do we check whether the data is table data?
return true
}
function eraseText() {
document.getElementById("editor_markdown").value = "";
document.getElementById("editor_rst_listtable").value = "";
document.getElementById("editor_rst_variant1").value = "";
document.getElementById("editor_rst_variant2").value = "";
}
function copy_markdown() {
var el = document.getElementById("editor_markdown")
el.select()
document.execCommand('copy')
}
function copy_rst_variant1() {
var el = document.getElementById("editor_rst_variant1")
el.select()
document.execCommand('copy')
}
function copy_rst_variant2() {
var el = document.getElementById("editor_rst_variant2")
el.select()
document.execCommand('copy')
}
function copy_rst_listtable() {
var el = document.getElementById("editor_rst_listtable")
el.select()
document.execCommand('copy')
}
</script>
<script src="conversion_functions.js"></script>
<script src="script.js"></script>
</body>
</html>
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"scripts": {
"test": "mocha"
}
}
Loading