Giter Site home page Giter Site logo

b-yond-infinite-network / md-to-adf Goto Github PK

View Code? Open in Web Editor NEW
39.0 5.0 5.0 2.42 MB

Markdown to Atlassian Document Format translation/traduction

License: Apache License 2.0

JavaScript 32.14% Gherkin 67.86%
adf jira confluence markdown markdown-to-adf markdown-to-jira markdown-to-confluence

md-to-adf's People

Contributors

dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

md-to-adf's Issues

Support images

Currently we don't support images.
we should extract the URL and push the image link so that we don't use the JIRA Media undocumented API but still have images compatibility...

Links are not formatted correctly

Hi, I tried using this library to translate some basic Markdown and received an unexpected result:

> console.log(JSON.stringify(require("md-to-adf")("link 1 <https://example.com> and link 2 [here [brackets] there](https://example.com)"), null, 2))
{
  "type": "doc",
  "content": [
    {
      "type": "paragraph",
      "content": [
        {
          "type": "text",
          "text": "link 1 <https://example.com> and link 2 [here [brackets] there](https://example.com)"
        }
      ]
    }
  ],
  "version": 1
}

Neither link is formatted correctly, although other compliant Markdown parsers translate them both properly as links, e.g.:

% pandoc -fmarkdown -thtml <<< "link 1 <https://example.com> and link 2 [here [brackets] there](https://example.com)"
<p>link 1 <a href="https://example.com"
class="uri">https://example.com</a> and link 2 <a
href="https://example.com">here [brackets] there</a></p>

Support strikethrough

Also very useful to be able to emphasis stuff that are not true anymore ๐Ÿ˜ƒ
code with _emphasis_ ?

Support divider

We need to support dividers since they are very useful to organize text


Backslash in the end should be hardBreak

Markdown backslash in the end of a line should be hardBreak in ADF. E.g.

one
\
\
two

should be

"content": [
  {
    "type": "text",
    "text": "one"
  },
  {
    "type": "hardBreak"
  },
  {
    "type": "hardBreak"
  },
  {
    "type": "text",
    "text": "two"
  }
]

Emoji are captured inside URLs

Input markdown:

โ€” *![alt text](https://localhost:4567/some/url)*

Output ADF:

{                                                                                                                                                      
  "type": "doc",                                                                                                                                       
  "content": [                                                                                                                                                
    {                                                                                                                                                  
      "type": "paragraph",                                                                                                                             
      "content": [                                                                                                                                     
        {                                                                                                                                              
          "type": "text",                                                                                                                              
          "text": "โ€” "                                                                                                                                 
        },                                                                                                                                             
        {                                                                                                                                              
          "type": "text",                                                                                                                              
          "text": "[alt text](http",                                                                                                                 
          "marks": [                                                                                                                                   
            {                                                                                                                                          
              "type": "em"                                                                                                                             
            }                                                                                                                                          
          ]                                                                                                                                            
        },                                                                                                                                             
        {                                                                                                                                              
          "type": "emoji",                                                                                                                             
          "attrs": {                                                                                                                                   
            "shortName": "//localhost"                                                                                                                 
          }                                                                                                                                            
        },                                                                                                                                             
        {                                                                                                                                              
          "type": "text",                                                                                                                              
          "text": "4567/some/url)"                                                                                                                 
        }                                                                                                                                              
      ]                                                                                                                                                
    }                                                                                                                                                  
  ],                                                                                                                                                   
  "version": 1                                                                                                                                         
}  

Matcher should avoid URLs in image or link syntax.

No break possible between Lists & List items are each their own list

Summary:

  1. Once a list has been started, the next paragraphs and lines are always a list
  2. The first non-list item becomes part of the previous list and the all subsequent lines are list items.
  3. List items are each their own list

Using the following markdown as test input:

**This is the first list:**

- bullet line one
- not indented line


**the 2nd list**

- 2nd list, 1st item
- 2nd list, 2nd item

In the output JSON, notice the following:

  1. The items of each of the lists are treated as two separate bullestLists even though they should be part of the content of the same one.
    • Just so happens to get visually rendered as one bullet list on Atlassian.
  2. Despite having two empty lines (so 3 consecutive newlines \n's), the 2nd paragraph header gets added as list item for the first list, instead of being on its own after an to the first list.
  3. All subsequent lines after a bullet list has started become part of the list, even if not prefixed with a -. Or they become content of the last element given as a list
{
    "type": "doc",
    "content": [
        {
            "type": "paragraph",
            "content": [
                {
                    "type": "text",
                    "text": "This is the first list:",
                    "marks": [
                        {
                            "type": "strong"
                        }
                    ]
                }
            ]
        },
        {
            "type": "bulletList",
            "content": [
                {
                    "type": "listItem",
                    "content": [
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "bullet line one"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "type": "bulletList",
            "content": [
                {
                    "type": "listItem",
                    "content": [
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "not indented line"
                                }
                            ]
                        },
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": " "
                                }
                            ]
                        },
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "the 2nd list",
                                    "marks": [
                                        {
                                            "type": "strong"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "type": "bulletList",
            "content": [
                {
                    "type": "listItem",
                    "content": [
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "2nd list, 1st item"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "type": "bulletList",
            "content": [
                {
                    "type": "listItem",
                    "content": [
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "2nd list, 2nd item"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ],
    "version": 1
}

It should be something like this:

{
    "type": "doc",
    "content": [
        {
            "type": "paragraph",
            "content": [
                {
                    "type": "text",
                    "text": "This is the first list:",
                    "marks": [
                        {
                            "type": "strong"
                        }
                    ]
                }
            ]
        },
        {
            "type": "bulletList",
            "content": [
                {
                    "type": "listItem",
                    "content": [
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "bullet line one"
                                }
                            ]
                        }
                    ]
                },
                {
                    "type": "listItem",
                    "content": [
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "not indented line"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "type": "paragraph",
            "content": [
                {
                    "type": "text",
                    "text": "the 2nd list",
                    "marks": [
                        {
                            "type": "strong"
                        }
                    ]
                }
            ]
        },
        {
            "type": "bulletList",
            "content": [
                {
                    "type": "listItem",
                    "content": [
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "2nd list, 1st item"
                                }
                            ]
                        }
                    ]
                },
                {
                    "type": "listItem",
                    "content": [
                        {
                            "type": "paragraph",
                            "content": [
                                {
                                    "type": "text",
                                    "text": "2nd list, 2nd item"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ],
    "version": 1
}

Ordered lists broken

Hi, I noticed ordered lists break after a paragraph:

const fnTranslate = require('md-to-adf')
const util = require('util')

myJIRAFormattedTextContent = "hello world\n1. foo\n2. bar"
const translatedADF = fnTranslate( myJIRAFormattedTextContent )
console.log(util.inspect(translatedADF, {showHidden: false, depth: null, colors: true}))

Logs this:

Document {
  attrs: { version: 1 },
  content: ContentNode {
    type: 'doc',
    minLength: 1,
    content: [
      Paragraph {
        content: ContentNode {
          type: 'paragraph',
          minLength: 1,
          content: [ Text { text: 'hello world', marks: null } ]
        }
      },
      OrderedList {
        content: ContentNode {
          type: 'orderedList',
          minLength: 1,
          content: [
            ListItem {
              content: ContentNode {
                type: 'listItem',
                minLength: 1,
                content: [
                  Paragraph {
                    content: ContentNode {
                      type: 'paragraph',
                      minLength: 1,
                      content: [ Text { text: 'foo', marks: null } ]
                    }
                  }
                ]
              }
            }
          ]
        },
        attrs: { order: '1' }
      },
      OrderedList {
        content: ContentNode {
          type: 'orderedList',
          minLength: 1,
          content: [
            ListItem {
              content: ContentNode {
                type: 'listItem',
                minLength: 1,
                content: [
                  Paragraph {
                    content: ContentNode {
                      type: 'paragraph',
                      minLength: 1,
                      content: [ Text { text: 'bar', marks: null } ]
                    }
                  }
                ]
              }
            }
          ]
        },
        attrs: { order: '2' }
      }
    ]
  }
}

Notice the 2 OrderedList when there should only be 1. I you remove hello world\n, it works as expected.

Support Github tables

Tables are very useful github extension to markdown

Cute And useful
Content from cell 1 Content from cell 2
Content in the first column Content in the second column

Support URLs and Email Addresses

Hi, I'm currently using this amazing library and works for most of the cases,
but It doesn't support the URLs and Email from MarkDown

they have to be formatted like links
https://www.markdownguide.org/basic-syntax/#links

instead of
https://www.markdownguide.org/basic-syntax/#urls-and-email-addresses

{ "type": "text", "text": "Duck Duck Go", "marks": [ { "type": "link", "attrs": { "href": "https://duckduckgo.com" } } ] }, { "type": "text", "text": " <https://www.markdownguide.org> <[email protected]>" }

Only a single hyperlink per paragraph appears to be detected

This is similar to #12 and #27, but different enough to mandate its own ticket.

Consider the following script md2adf.js taking markdown on stdin and giving adf on stdout. I.e. one of the simplest possible uses of this library:

#!/usr/bin/nodejs

const fnTranslate    = require( process.env["NPM_CONFIG_PREFIX"] +
    '/lib/node_modules/md-to-adf' )

process.stdin.on("data", data => {
    console.log(JSON.stringify(fnTranslate(data.toString())))
})

When feeding it with input using the following script: (deemed more overviewable than any more verbose example I would be able to produce in pure javascript)

#!/bin/sh -eu

working_desc='Markdown with one hyperlink works as expected:'
working_md='Markdown may contain [hyper links](https://example.com/) '

broken_desc='As soon as one adds a second one it breaks though:'
broken_md="$( echo 'Markdown may contain [hyper links](https://example.com/) ' \
  'note that plural means more than merely one [link](https://example.org/)' )"

workaround_desc='Working around it?:'
workaround_md="$( printf '%s\\n\\n%s\\n' \
  'Adding hard paragraph breaks [hyper links](https://example.com/)' \
  'seems to be a work around [link](https://example.org/)' )"

for example in working broken workaround; do
  echo $( eval echo "\$${example}_desc" )
  echo "$( eval echo "\$${example}_md" )" | ./md2adf.js
  echo
done

Running the above gives the following output:

Markdown with one hyperlink works as expected:
{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Markdown may contain "},{"type":"text","text":"hyper links","marks":[{"type":"link","attrs":{"href":"https://example.com/"}}]}]}],"version":1}

As soon as one adds a second one it breaks though:
{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Markdown may contain [hyper links](https://example.com/) note that plural means more than merely one "},{"type":"text","text":"link","marks":[{"type":"link","attrs":{"href":"https://example.org/"}}]}]}],"version":1}

Working around it?:
{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Adding hard paragraph breaks "},{"type":"text","text":"hyper links","marks":[{"type":"link","attrs":{"href":"https://example.com/"}}]}]},{"type":"paragraph","content":[{"type":"text","text":"seems to be a work around "},{"type":"text","text":"link","marks":[{"type":"link","attrs":{"href":"https://example.org/"}}]}]}],"version":1}

I did briefly open up the source code, but got reminded immediately that javascript isn't my language. All I noticed was that the library appears to do string matching in markdownParsing.js rather than using some kind of context aware parsing engine. Without being an expert, I suspect that is a too simplistic approach for more than the most simple use cases.

Regarding the workaround; Having to add hard paragraph breaks is not ideal, but removing those manually is at least a lot less work than fiddling with hyperlinks in Atlassians web browser interface.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.