Извлеките CSS из SVG и переместите его в отдельный файл [закрыто]CSS

Разбираемся в CSS
Ответить
Anonymous
 Извлеките CSS из SVG и переместите его в отдельный файл [закрыто]

Сообщение Anonymous »

mkdir каталог-вашего-проекта
cd каталог-вашего-проекта
mkdir svgs
npm init -y
npm install xmldom
нажмите имя_скрипта.js

Код: Выделить всё

const fs = require('fs');
const path = require('path');
const { DOMParser, XMLSerializer } = require('xmldom');

// Function to generate unique class names
let classCounter = 0;
const generateClassName = () => `svg-class-${classCounter++}`;

// Function to convert SVG styles to classes and return the modified SVG and extracted CSS
function convertSVGStylesToClasses(svgString, uniqueSuffix) {
const parser = new DOMParser();
const svgDoc = parser.parseFromString(svgString, "image/svg+xml");

let styles = "";
let index = 0;
let existingClasses = {};
traverseNodes(svgDoc.documentElement);
extractStyleElements(svgDoc);
function traverseNodes(node) {
if (node.nodeType === 1) { // Element node
const attributes = ["fill", "stroke", "stroke-width"];
let style = "";
let hasStyle = false;

attributes.forEach(attr => {
if (node.hasAttribute(attr)) {
style += `${attr}: ${node.getAttribute(attr)}; `;
node.removeAttribute(attr);
hasStyle = true;
}
});

// Process existing class attributes
if (node.hasAttribute("class")) {
const existingClass = node.getAttribute("class").trim();
if (existingClass) {
const newClass = existingClasses[existingClass] || `svg-class-${uniqueSuffix}-${index++}`;
node.setAttribute("class", newClass);
existingClasses[existingClass] = newClass;
}
}
if (node.hasAttribute('style')) {
const inlineStyle = node.getAttribute('style');
style += `${inlineStyle} `;
node.removeAttribute('style');
hasStyle = true;
}

if (hasStyle) {
const className = `svg-class-${uniqueSuffix}-${index++}`;
node.setAttribute("class", className);
styles += `.${className} { ${style} }\n`;
}
}

// Recursively traverse child nodes
for (let child = node.firstChild; child; child = child.nextSibling) {
traverseNodes(child);
}
}
const modifiedSVG = new XMLSerializer().serializeToString(svgDoc);
return { svg: modifiedSVG, css: styles };

function extractStyleElements(svgDoc) {
// Append existing styles from  tags
const existingStyles = svgDoc.getElementsByTagName('style');
for (let i = 0; i < existingStyles.length; i++) {
const styleContent = existingStyles[i].textContent.trim();
styles += styleContent.replace(/(\.)([a-zA-Z0-9_-]+)/g, (match, prefix, className) => {
if (existingClasses.hasOwnProperty(className)) {
return `${prefix}${existingClasses[className]}`;
}
const newClassName = `svg-class-${uniqueSuffix}-${index++}`;
existingClasses[className] = newClassName;
return `${prefix}${newClassName}`;
}) + '\n';
existingStyles[i].parentNode.removeChild(existingStyles[i]);
}

// const styleElement = svgDoc.createElementNS("http://www.w3.org/2000/svg", "style");
// styleElement.textContent = styles;
// svgDoc.documentElement.insertBefore(styleElement, svgDoc.documentElement.firstChild);

}
}

// Function to process SVG files in a directory and save processed files in another directory
function processSVGFiles(inputDirectory, outputDirectory) {
const files = fs.readdirSync(inputDirectory).filter(file => path.extname(file) === '.svg');
let combinedStyles = "";

files.forEach((file, fileIndex) => {
const filePath = path.join(inputDirectory, file);
const svgContent = fs.readFileSync(filePath, 'utf-8');

const uniqueSuffix = `file${fileIndex}`;
const { svg: modifiedSVG, css, existingClasses } = convertSVGStylesToClasses(svgContent, uniqueSuffix);
// combinedStyles += css;

if(existingClasses){
// Replace existing class names in SVG content
Object.keys(existingClasses).forEach(existingClass => {
const regex = new RegExp(`\\.${existingClass}`, 'g');
modifiedSVG = modifiedSVG.replace(regex, `.${existingClasses[existingClass]}`);
});
}

const outputFilePath = path.join(outputDirectory, file);  // Use original filename
fs.writeFileSync(outputFilePath, modifiedSVG, 'utf-8');
console.log(`Processed ${file}`);

// Append CSS for this file to combined styles
combinedStyles += css.replace(/(\.)([a-zA-Z0-9_-]+)/g, (match, prefix, className) => {
if (existingClasses && existingClasses.hasOwnProperty(className)) {
return `${prefix}${existingClasses[className]}`;
}
return match;
});
});

const cssFilePath = path.join(outputDirectory, 'combined_styles.css');
fs.writeFileSync(cssFilePath, combinedStyles, 'utf-8');
console.log(`Combined styles written to ${cssFilePath}`);
}

// Specify the input and output directories
const inputDirectory = './svgs';
const outputDirectory = './processed_svgs';

// Create the output directory if it doesn't exist
if (!fs.existsSync(outputDirectory)) {
fs.mkdirSync(outputDirectory);
}

// Process SVG files from inputDirectory and save processed files to outputDirectory
processSVGFiles(inputDirectory, outputDirectory);

каталог-вашего-проекта/

├── svgs/
│ ├── svg1.svg
│ ├── svg2.svg
│ ├── svg3.svg
│ └── ... (другие ваши файлы SVG)

├── node_modules/
│ └── ... (генерируется после запуска npm install)

├── package.json

├── имя_скрипта.js

└── Combined_styles.css (генерируется сценарием)
Пожалуйста, проверьте, работает это или нет
пробовал несколько способов для

Код: Выделить всё

const HtmlWebpackPlugin = require('html-webpack-plugin');
const { AngularWebpackPlugin } = require('@ngtools/webpack');

module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
inject: 'body',
}),
new AngularWebpackPlugin({
tsconfig: './tsconfig.app.json',
directTemplateLoading: false,
}),
function () {
this.hooks.compilation.tap('HtmlWebpackPluginHooks', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync(
'NonceTag',
(data, cb) => {
['scripts', 'headTags'].forEach((section) => {
data[section].forEach((tag) => {
if (tag.tagName === 'script') {
tag.attributes.nonce = 'your_actual_nonce_value'; // Replace with your actual nonce value
}
});
});
cb(null, data);
}
);
});
},
],
};

{
"projects": {
"your-project-name": {
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./webpack.config.js"
},
"outputPath": "dist/your-project-name",
"index": "src/index.html",
// other options...
}
},
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"customWebpackConfig": {
"path": "./webpack.config.js"
}
}
}
}
}
}
}


Код: Выделить всё

indexTransform: (html) => {
const nonceValue = 'your_actual_nonce_value'; // Replace with your actual nonce value
const scriptTagRegex = //g;
const modifiedHtml = html.replace(scriptTagRegex, (match, attributes) => {
if (!attributes.includes('nonce')) {
return ``;
}
return match;
});
return modifiedHtml;
},



Подробнее здесь: https://stackoverflow.com/questions/787 ... erate-file
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «CSS»