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

Workflow question: converting SVGs to PNGs #449

Closed
SachaG opened this issue Sep 17, 2016 · 9 comments
Closed

Workflow question: converting SVGs to PNGs #449

SachaG opened this issue Sep 17, 2016 · 9 comments

Comments

@SachaG
Copy link
Contributor

SachaG commented Sep 17, 2016

Sorry in advance if this is a bit off-topic, but I have some SVG graphs generated by React inside Gatsby, and I would love to convert them into PNG preview images to make it easier to share them on Twitter.

What would be the best way to integrate this into the overall Gatbsy workflow? Could the conversion be done at build time, and the resulting images stored in public?

@SachaG
Copy link
Contributor Author

SachaG commented Sep 17, 2016

I guess another way to phrase my question would be, given that I have a bunch of SVG charts built by Gatsby, how can I access the resulting markup at build time, hopefully without having to manually create a new page for each individual chart?

@KyleAMathews
Copy link
Contributor

On my phone but search for the postBuild hook. Export it from
gatsby-node.js and it gets called when build is done and you can do
whatever you want there.
On Fri, Sep 16, 2016 at 10:12 PM Sacha Greif [email protected]
wrote:

I guess another way to phrase my question would be, given that I have a
bunch of SVG charts built by Gatsby, how can I access the resulting markup
at build time, hopefully without having to manually create a new page for
each individual chart?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#449 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEVh68hhhj2AsHQsFtPWHJKo6uhoHZAks5qq3bagaJpZM4J_gen
.

@SachaG
Copy link
Contributor Author

SachaG commented Sep 17, 2016

Thanks for the tip! Correct me if I'm wrong, but that hook doesn't seem to pass the markup directly, right? It does pass the file path so I guess I could always retrieve the markup like that.

I'm not sure what would be the best way to then access the SVGs though. Maybe have one separate page that contains all of them, and then somehow parse that?

@KyleAMathews
Copy link
Contributor

Right I don't think the pages themselves are available but they'll be in
/public now so you can grab them there.
On Sat, Sep 17, 2016 at 12:05 AM Sacha Greif [email protected]
wrote:

Thanks for the tip! Correct me if I'm wrong, but that hook doesn't seem to
pass the markup directly, right? It does pass the file path so I guess I
could always retrieve the markup like that.

I'm not sure what would be the best way to then access the SVGs though.
Maybe have one separate page that contains all of them, and then somehow
parse that?


You are receiving this because you commented.

Reply to this email directly, view it on GitHub
#449 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEVh3iFkrp1q53784Aj7OQ9reoijZ4Hks5qq5FLgaJpZM4J_gen
.

@KyleAMathews
Copy link
Contributor

Perhaps just use cheerio to zoom through all the html pages and pull out
svgs.
On Sat, Sep 17, 2016 at 12:11 AM Kyle Mathews [email protected]
wrote:

Right I don't think the pages themselves are available but they'll be in
/public now so you can grab them there.
On Sat, Sep 17, 2016 at 12:05 AM Sacha Greif [email protected]
wrote:

Thanks for the tip! Correct me if I'm wrong, but that hook doesn't seem
to pass the markup directly, right? It does pass the file path so I guess I
could always retrieve the markup like that.

I'm not sure what would be the best way to then access the SVGs though.
Maybe have one separate page that contains all of them, and then somehow
parse that?


You are receiving this because you commented.

Reply to this email directly, view it on GitHub
#449 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEVh3iFkrp1q53784Aj7OQ9reoijZ4Hks5qq5FLgaJpZM4J_gen
.

@SachaG
Copy link
Contributor Author

SachaG commented Sep 17, 2016

Actually, I'm not sure if my idea can work after all… I want to make it easy to share SVG graphs as Twitter cards, but it looks like that would require each graph to have its own page with its own meta tags, I don't think you can just pass an image URL to Twitter. So I don't think this is possible until we get programmatic routes, sadly.

@SachaG
Copy link
Contributor Author

SachaG commented Sep 17, 2016

Unless maybe I generated new HTML files myself containing the right meta tags in the postBuild hook. Seems a bit involved but maybe it could work…?

@SachaG
Copy link
Contributor Author

SachaG commented Sep 18, 2016

Here's what I ended up with. Works pretty well!

exports.postBuild = function (pages, callback) {
  const svgpath = 'public/svgcontainer/index.html'

  fs.readFile(svgpath, 'utf8', (err1, data) => {
    if (err1) throw err1

    // parse SVGContainer file
    const $ = cheerio.load(data)
    const svgs = $('.svg-block')

    // iterate over SVG blocks
    svgs.each((i, svg) => {
      const svgId = $(svg).attr('id')
      const svgContents = $(svg).find('.recharts-wrapper').html()
      const svgPath = `public/exports/svg/${svgId}.svg`
      const pngPath = `public/exports/png/${svgId}.png`

      console.log(`// exporting ${svgId}…`)

      // export SVG

      fs.exists(svgPath, exists => {
        const options = exists ? {} : { flag: 'wx' }
        fs.writeFile(svgPath, svgContents, options, (err, data) => {
          if (err) console.log(err)
        })
      })

      // export PNG

      // see https://cloudconvert.com/api/convert/svg-to-png
      try {
        cloudconvert.convert({
          inputformat: 'svg',
          outputformat: 'png',
          input: 'raw',
          filename: `${svgId}.svg`,
          file: svgContents,
        }).pipe(fs.createWriteStream(pngPath))
      } catch (err) { console.log(err) }
    })
  })

  callback()
}

Where svgcontainer is a React component containing all my SVG graphs.

@SachaG SachaG closed this as completed Sep 18, 2016
@KyleAMathews
Copy link
Contributor

Nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants