{"id":13343064,"url":"https://github.com/RouninMedia/SVG-to-Data-URL","last_synced_at":"2025-03-12T04:32:04.061Z","repository":{"id":93004182,"uuid":"317913071","full_name":"RouninMedia/SVG-to-Data-URL","owner":"RouninMedia","description":"SVG to Data URL is a function which converts any SVG into a Data URL. An Ashiva Component.","archived":false,"fork":false,"pushed_at":"2021-09-04T10:25:02.000Z","size":61,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-24T15:38:06.696Z","etag":null,"topics":["data-uri","data-url","javascript","svg","xml"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RouninMedia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-02T15:54:36.000Z","updated_at":"2021-09-04T10:25:05.000Z","dependencies_parsed_at":"2023-03-13T17:23:26.444Z","dependency_job_id":null,"html_url":"https://github.com/RouninMedia/SVG-to-Data-URL","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RouninMedia%2FSVG-to-Data-URL","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RouninMedia%2FSVG-to-Data-URL/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RouninMedia%2FSVG-to-Data-URL/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RouninMedia%2FSVG-to-Data-URL/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RouninMedia","download_url":"https://codeload.github.com/RouninMedia/SVG-to-Data-URL/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243158977,"owners_count":20245668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-uri","data-url","javascript","svg","xml"],"created_at":"2024-07-29T19:30:36.930Z","updated_at":"2025-03-12T04:32:04.055Z","avatar_url":"https://github.com/RouninMedia.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SVG to Data URL\n\nThe function `SVGtoDataURL(svg)` converts any **valid SVG** into a **Data URL**.\n\nThe function `dataURLtoSVG(dataURL)` converts a **Data URL** which satisfies certain criteria into a **valid SVG**.\n\n______\n\n## SVG to Data URL Function\n\n### Step 1\n\nThe `SVGtoDataURL(svg)` function verifies that the string passed to the function:\n\n - has a valid **SVG Namespace**\n - represents **well-formed XML**\n\nIf either or both conditions are not met, the `SVGtoDataURL(svg)` function will return a verbose error detailing how the string may be fixed.\n\n### Step 2\n\nIf both the conditions above are met, the `SVGtoDataURL(svg)` function returns the validated SVG as a **Data URL**.\n\n________\n\n### `SVGtoDataURL(svg)` :\n```\nconst SVGToDataURL = (SVG) =\u003e {\n\n  let output;\n  const { SVGNamespaceMatches, wellFormedXML, parsedDocument } = validateSVG(SVG);\n\n  // ASSIGN TO OUTPUT: SVG CONVERTED INTO DATA URL\n  if ((SVGNamespaceMatches === true) \u0026\u0026 (wellFormedXML === true)) {\n\n    let dataURL = SVG;\n    dataURL = dataURL.replace(/(\\s*\\n)*\\s+/g, ' ');\n    dataURL = dataURL.replace(/[\\\"|\\']/g, '%22');\n    dataURL = dataURL.replace(/\\\u003e\\s+\\\u003c/g, '\u003e\u003c');\n    dataURL = dataURL.replace(/\\s\\/\\\u003e/g, '/\u003e');\n    dataURL = dataURL.replace(/\\s*\\:\\s*/g, ':');\n    dataURL = dataURL.replace(/\\s*\\;\\s*/g, ';');\n    dataURL = dataURL.replace(/\\s*\\{\\s*/g, '{');\n    dataURL = dataURL.replace(/\\s*\\}\\s*/g, '}');\n    dataURL = dataURL.replace(/\\s*\\,\\s*/g, ',');\n    \n    dataURL = dataURL.trim();\n\n    const characterArray = dataURL.split('');\n\n    for (let i = 0; i \u003c characterArray.length; i++) {\n\n      if (characterArray[i].match(/[A-Za-z0-9\\.\\,\\;\\:\\/\\*\\-\\=\\_\\~\\'\\!\\$\\@]/) === null) {\n\n      \tcharacterArray[i] = encodeURIComponent(characterArray[i]);\n      }\n    }\n\n    dataURL = 'data:image/svg+xml,' + characterArray.join('');\n\n    output = dataURL;\n  }\n\n\n  // ELSE ASSIGN TO OUTPUT: ASHIVA CONSOLE WITH ANALYSIS OF SVG CODE\n  else {\n\n    output = consoleSVG({SVG, parsedDocument, SVGNamespaceMatches, wellFormedXML});\n  }\n\n  return output;\n}\n\n```\n\n______\n\n## Data URL to SVG Function\n\nNaturally, a function like `SVGtoDataURL(svg)`, above, needs a corresponding function which can perform the same transformation in reverse.\n\n`dataURLtoSVG(dataURL)` will convert the **Data URL** (which conforms to certain constraints) into a valid, namespaced, well-formed **SVG**.\n\nIf the function cannot build an **SVG** out of the **Data URL**, it will return a verbose error, explaining why not.\n\n### Step 1\n\nThe `dataURLtoSVG(dataURL)` function converts the **Data URL** provided into an **unformatted SVG**.\n\n### Step 2\n\nThe `dataURLtoSVG(dataURL)` function then verifies that the **unformatted SVG**:\n\n - has a valid **SVG Namespace**\n - represents **well-formed XML**\n\nIf either or both conditions are not met, the `dataURLtoSVG(dataURL)` function will return a verbose error detailing how the string may be fixed.\n\n### Step 3\n\nIf both the conditions above are met, the `dataURLtoSVG(dataURL)` function will format the **valid SVG** and return a **formatted, valid SVG**.\n\n________\n\n### `dataURLtoSVG(dataURL)` :\n\n```\nconst dataURLtoSVG = (dataURL) =\u003e {\n  \n  let output;\n\n\n  // CONVERT DATA URL TO SVG\n  let SVG = dataURL;\n\n  SVG = SVG.replace('data:image/svg+xml,', '');\n  SVG = decodeURIComponent(SVG);\n  SVG = SVG.replace(/\\'/g, '\"');\n  SVG = SVG.trim();\n\n\n  // VALIDATE SVG\n  const { SVGNamespaceMatches, wellFormedXML, parsedDocument } = validateSVG(SVG);\n\n\n  // ASSIGN TO OUTPUT: FORMATTED SVG\n  if ((SVGNamespaceMatches === true) \u0026\u0026 (wellFormedXML === true)) {\n\n    // ADD A NEWLINE BEFORE EACH SVG ELEMENT\n    SVG = SVG.replace('\u003e\u003c', '\u003e\\n\\n\u003c');\n    SVG = SVG.replace(/\\\u003e\\\u003c\\/svg\\\u003e$/, '\u003e\\n\\n\u003c/svg\u003e');\n    SVG = SVG.replace(/\u003e\u003c/g, '\u003e\\n\u003c');\n\n    // FORMAT SVG ROOT ELEMENT\n    let svgRoot = SVG.match(/^\\\u003csvg([^\\\u003e]+?)\\\u003e/)[0];\n    svgRootPieces = svgRoot.split('\"');\n\n    for (let i = 0; i \u003c svgRootPieces.length; i = i + 2) {\n\n      svgRootPieces[i] = svgRootPieces[i].split(' ').join('\\n  ');\n    }\n\n    let reformattedRoot = svgRootPieces.join('\"');\n    SVG = SVG.replace(svgRoot, reformattedRoot);\n\n    output = SVG;\n  }\n\n\n  // ELSE ASSIGN TO OUTPUT: ASHIVA CONSOLE WITH ANALYSIS OF SVG CODE\n  else {\n\n    output = consoleSVG({SVG, parsedDocument, SVGNamespaceMatches, wellFormedXML});\n  }\n\n\n  return output;\n}\n\n```\n______\n\n## Two more functions\n\nBoth `SVGtoDataURL(svg)` and `dataURLtoSVG(dataURL)` reference two further functions:\n\n - `validateSVG(SVG)` which checks:\n   - if the SVG starts with the right namespace; and\n   - if the SVG represents well-formed XML\n   \n -  `consoleSVG(dataObject)` which returns a verbose Ashiva Console Message detailing where the SVG is invalid\n\n________\n\n### `validateSVG(SVG)` :\n\n```\nconst validateSVG = (SVG) =\u003e {\n  \n  // VERIFY SVG NAMESPACE MATCHES\n  const SVGNamespace = SVG.trim().replace(/\\s+/g, ' ').substr(0, 39);\n  const SVGNamespaceMatch = '\u003csvg xmlns=\"http://www.w3.org/2000/svg\"';\n  const SVGNamespaceMatches = (SVGNamespace === SVGNamespaceMatch) ? true : false;\n\n  // VERIFY SVG REPRESENTS WELL-FORMED XML\n  const XMLParser = new DOMParser();\n  const parsedDocument = XMLParser.parseFromString(SVG, 'image/svg+xml');\n  const wellFormedXML = (parsedDocument.documentElement.nodeName.indexOf('parsererror') \u003c 0) ? true : false;\n\n  return { SVGNamespaceMatches, wellFormedXML, parsedDocument };\n}\n```\n\n________\n\n### `consoleSVG(dataObject)` :\n\n```\nconst consoleSVG = (dataObject) =\u003e {\n\n  const { SVG, parsedDocument, SVGNamespaceMatches, wellFormedXML } = dataObject;\n\n  const SVGTitle = SVG.split('\u003c/title\u003e')[0].split('\u003ctitle\u003e')[1];\n\n  let console = '';\n  console += '\\n\\n\u003c!--\\n\\n';\n  console += '  ⚠️ Ashiva Console:\\n\\n';\n\n  if (SVGTitle !== undefined) {\n\n    console += '  ⚠️ Issue: SVG Document with title \"' + SVGTitle + '\" is not validating as an SVG.\\n\\n';\n  }\n\n  else {\n\n    console += '  ⚠️ Issue: SVG Document is not validating as an SVG.\\n\\n';\n  }\n\n  switch (true) {\n\n    case ((SVGNamespaceMatches === false) \u0026\u0026 (wellFormedXML === false)) :\n      console += '  ⚠️ Analysis: This SVG lacks a valid SVG Namespace AND this SVG is not well-formed XML.\\n\\n';\n      break;\n\n    case (SVGNamespaceMatches === false) :\n      console += '  ⚠️ Analysis: This SVG lacks a valid SVG Namespace.\\n\\n';\n      break;\n\n    case (wellFormedXML === false) :\n      console += '  ⚠️ Analysis: This SVG is not well-formed XML.\\n\\n';\n      break;\n  }\n\n\n  if (SVGNamespaceMatches === false) {\n\n    console += '  ⚠️ Next Step: Ensure this SVG begins with the following valid namespace:\\n\\n';\n    console += '      xmlns=\"http://www.w3.org/2000/svg\"\\n\\n';\n  }\n\n\n  if (wellFormedXML === false) {\n\n    console += '  ⚠️ Next Step: Fix the XML of this SVG by following the error report below.\\n\\n';\n    console += '  ⚠️ Error Report: ' + parsedDocument.documentElement.textContent.replace(/\\n/g, '\\n\\n      ') + '\\n\\n';\n  }\n\n  console += '--\u003e\\n\\n';\n\n  return console;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRouninMedia%2FSVG-to-Data-URL","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRouninMedia%2FSVG-to-Data-URL","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRouninMedia%2FSVG-to-Data-URL/lists"}