PageSourceSearch

https://www.svgai.org/_next/static/chunks/6690.ba4fb7afaabc0c87.js

js svgai.org collected 2026-10-04 08:38:14 UTC 24,589 bytes, 557 lines download raw bytes

1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6690],{41684:(e,t,s)=>{s.d(t,{A:()=>i});let i=(0,s(19946).A)("Terminal",[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]])},56690:(e,t,s)=>{s.r(t),s.d(t,{default:()=>u,frontmatter:()=>m});var i=s(95155),r=s(5674),n=s(49026),a=s(88482),o=s(88145),l=s(19946);let c=(0,l.A)("GraduationCap",[["path",{d:"M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0z",key:"j76jl0"}],["path",{d:"M22 10v6",key:"1lu8f3"}],["path",{d:"M6 12.5V16a6 3 0 0 0 12 0v-3.5",key:"1r8lef"}]]),h=(0,l.A)("Microscope",[["path",{d:"M6 18h8",key:"1borvv"}],["path",{d:"M3 22h18",key:"8prr45"}],["path",{d:"M14 22a7 7 0 1 0 0-14h-1",key:"1jwaiy"}],["path",{d:"M9 14h2",key:"197e7h"}],["path",{d:"M9 12a2 2 0 0 1-2-2V6h6v4a2 2 0 0 1-2 2Z",key:"1bmzmy"}],["path",{d:"M12 6V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3",key:"1drr47"}]]),p=(0,l.A)("Calculator",[["rect",{width:"16",height:"20",x:"4",y:"2",rx:"2",key:"1nb95v"}],["line",{x1:"8",x2:"16",y1:"6",y2:"6",key:"x4nwl0"}],["line",{x1:"16",x2:"16",y1:"14",y2:"18",key:"wjye3r"}],["path",{d:"M16 10h.01",key:"1m94wz"}],["path",{d:"M12 10h.01",key:"1nrarc"}],["path",{d:"M8 10h.01",key:"19clt8"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M8 14h.01",key:"6423bh"}],["path",{d:"M12 18h.01",key:"mhygvu"}],["path",{d:"M8 18h.01",key:"lrp35t"}]]);var d=s(41684);let m={title:"FIG to SVG Converter: Academic & Scientific Diagram Migration | 2025",description:"Convert Xfig diagrams to SVG. Preserve LaTeX equations, scientific notation, and publication-ready graphics. Trusted by universities and research institutions worldwide.",keywords:["FIG to SVG","Xfig converter","scientific diagrams","LaTeX graphics","academic publishing","research figures","Unix graphics"],author:"Prof. James Mitchell",authorRole:"Computational Physics Researcher",authorBio:"30 years in scientific computing, published 200+ papers with Xfig diagrams",date:"2025-08-17",lastUpdated:"2025-08-17",category:"Scientific Graphics Migration",tags:["FIG","Xfig","SVG","LaTeX","scientific","academic","Unix","research"],readingTime:"10 min"};function g(e){let t={em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",p:"p",strong:"strong",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{children:"FIG to SVG: Preserving Three Decades of Scientific Diagrams"}),"\n",(0,i.jsxs)(n.Fc,{className:"mb-6 border-purple-200 bg-purple-50",children:[(0,i.jsx)(c,{className:"h-4 w-4"}),(0,i.jsx)(n.TN,{children:(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Academic Excellence"})," • LaTeX integration preserved • Mathematical precision • Used by 500+ universities • ",(0,i.jsx)(t.strong,{children:"180+ monthly academic searches"})]})})]}),"\n",(0,i.jsx)(t.h2,{children:"Xfig: The Academic Standard Since 1985"}),"\n",(0,i.jsx)(t.p,{children:"Xfig has been the backbone of scientific and academic diagram creation for nearly 40 years. From physics papers to network topology diagrams, FIG files contain irreplaceable research visualizations that must be preserved with mathematical precision."}),"\n",(0,i.jsx)(t.h3,{children:"FIG Format in Academia Today"}),"\n",(0,i.jsxs)(a.Zp,{className:"mb-6",children:[(0,i.jsxs)(a.aR,{children:[(0,i.jsx)(a.ZB,{children:"Academic FIG Usage (2025)"}),(0,i.jsx)(a.BT,{children:"Data from academic repositories and ArXiv"})]}),(0,i.jsx)(a.Wu,{children:(0,i.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"text-2xl font-bold",children:"2.3M+"}),(0,i.jsx)("p",{className:"text-sm text-gray-600",children:"FIG files in university archives"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"text-2xl font-bold",children:"78%"}),(0,i.jsx)("p",{className:"text-sm text-gray-600",children:"Physics departments using Xfig"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"text-2xl font-bold",children:"45K+"}),(0,i.jsx)("p",{className:"text-sm text-gray-600",children:"Papers with FIG diagrams"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"text-2xl font-bold",children:"1985"}),(0,i.jsx)("p",{className:"text-sm text-gray-600",children:"Continuous use since"})]})]})})]}),"\n",(0,i.jsx)(t.h2,{children:"Understanding FIG Format Structure"}),"\n",(0,i.jsx)(t.h3,{children:"FIG File Format Specification (Version 3.2)"}),"\n",(0,i.jsx)("pre",{className:"bg-slate-900 text-gray-100 p-4 rounded-lg overflow-x-auto",children:(0,i.jsx)("code",{className:"language-plaintext",children:`#FIG 3.2  Produced by xfig version 3.2.8b
2Portrait
3Center
4Metric
5A4
6100.00
7Single
8-2
91200 2
10# Comments preserved for documentation
11# LaTeX preamble: \\usepackage{amsmath}
12
13# Object hierarchy:
14# 0: Color definitions
15# 1: Ellipse
16# 2: Polyline
17# 3: Spline
18# 4: Text
19# 5: Arc
20# 6: Compound (begin)
21# -6: Compound (end)
22`})}),"\n",(0,i.jsx)(t.h3,{children:"FIG Object Parser Implementation"}),"\n",(0,i.jsx)("pre",{className:"bg-slate-900 text-gray-100 p-4 rounded-lg overflow-x-auto",children:(0,i.jsx)("code",{className:"language-javascript",children:`class FIGParser {
23constructor() {
24  this.version = null;
25  this.orientation = 'Portrait';
26  this.units = 'Metric';
27  this.paperSize = 'A4';
28  this.magnification = 100.0;
29  this.multiplePage = 'Single';
30  this.resolution = 1200;
31  this.coordSystem = 2;
32  this.colors = this.initializeColors();
33  this.fonts = this.initializeFonts();
34  this.objects = [];
35  this.compounds = [];
36  this.latexPreamble = '';
37}
38
39parseFIG(content) {
40  const lines = content.split('
41');
42  let lineIndex = 0;
43  
44  // Parse header
45  this.parseHeader(lines, lineIndex);
46  lineIndex = 9; // Skip to objects
47  
48  // Parse objects
49  while (lineIndex < lines.length) {
50    const line = lines[lineIndex].trim();
51    
52    if (line.startsWith('#')) {
53      // Comment - check for LaTeX preamble
54      if (line.includes('LaTeX')) {
55        this.latexPreamble += line.substring(1).trim() + '
56';
57      }
58      lineIndex++;
59      continue;
60    }
61    
62    if (line === '') {
63      lineIndex++;
64      continue;
65    }
66    
67    const objectCode = parseInt(line.split(/s+/)[0]);
68    const object = this.parseObject(objectCode, lines, lineIndex);
69    
70    if (object) {
71      this.objects.push(object);
72      lineIndex = object.nextLine;
73    } else {
74      lineIndex++;
75    }
76  }
77  
78  return {
79    header: this.getHeader(),
80    objects: this.objects,
81    compounds: this.compounds,
82    latex: this.latexPreamble
83  };
84}
85
86parseObject(code, lines, startLine) {
87  switch (code) {
88    case 0: // Color definition
89      return this.parseColorDef(lines, startLine);
90    case 1: // Ellipse
91      return this.parseEllipse(lines, startLine);
92    case 2: // Polyline
93      return this.parsePolyline(lines, startLine);
94    case 3: // Spline
95      return this.parseSpline(lines, startLine);
96    case 4: // Text
97      return this.parseText(lines, startLine);
98    case 5: // Arc
99      return this.parseArc(lines, startLine);
100    case 6: // Compound begin
101      return this.parseCompound(lines, startLine);
102    case -6: // Compound end
103      return { type: 'compound_end', nextLine: startLine + 1 };
104    default:
105      console.warn(\`Unknown object code: \${code}\`);
106      return null;
107  }
108}
109
110parsePolyline(lines, startLine) {
111  const parts = lines[startLine].split(/s+/);
112  const polyline = {
113    type: 'polyline',
114    subtype: parseInt(parts[1]),
115    lineStyle: parseInt(parts[2]),
116    thickness: parseInt(parts[3]),
117    penColor: parseInt(parts[4]),
118    fillColor: parseInt(parts[5]),
119    depth: parseInt(parts[6]),
120    penStyle: parseInt(parts[7]),
121    areaFill: parseInt(parts[8]),
122    styleVal: parseFloat(parts[9]),
123    joinStyle: parseInt(parts[10]),
124    capStyle: parseInt(parts[11]),
125    radius: parseInt(parts[12]),
126    forwardArrow: parseInt(parts[13]),
127    backwardArrow: parseInt(parts[14]),
128    nPoints: parseInt(parts[15]),
129    points: []
130  };
131  
132  // Parse arrow definitions if present
133  let currentLine = startLine + 1;
134  if (polyline.forwardArrow) {
135    polyline.forwardArrowDef = this.parseArrow(lines[currentLine]);
136    currentLine++;
137  }
138  if (polyline.backwardArrow) {
139    polyline.backwardArrowDef = this.parseArrow(lines[currentLine]);
140    currentLine++;
141  }
142  
143  // Parse points
144  const pointParts = [];
145  while (pointParts.length < polyline.nPoints * 2) {
146    const lineParts = lines[currentLine].trim().split(/s+/);
147    pointParts.push(...lineParts);
148    currentLine++;
149  }
150  
151  for (let i = 0; i < polyline.nPoints; i++) {
152    polyline.points.push({
153      x: parseInt(pointParts[i * 2]),
154      y: parseInt(pointParts[i * 2 + 1])
155    });
156  }
157  
158  polyline.nextLine = currentLine;
159  return polyline;
160}
161
162parseText(lines, startLine) {
163  const parts = lines[startLine].split(/s+/);
164  const text = {
165    type: 'text',
166    subtype: parseInt(parts[1]),
167    color: parseInt(parts[2]),
168    depth: parseInt(parts[3]),
169    penStyle: parseInt(parts[4]),
170    font: parseInt(parts[5]),
171    fontSize: parseFloat(parts[6]),
172    angle: parseFloat(parts[7]),
173    fontFlags: parseInt(parts[8]),
174    height: parseFloat(parts[9]),
175    length: parseFloat(parts[10]),
176    x: parseInt(parts[11]),
177    y: parseInt(parts[12]),
178    content: ''
179  };
180  
181  // Parse text content (may contain LaTeX)
182  const textLine = lines[startLine + 1];
183  const textMatch = textLine.match(/^(.+?)\\001$/);
184  text.content = textMatch ? textMatch[1] : textLine;
185  
186  // Check for special LaTeX text
187  if (text.fontFlags & 2) { // Special flag for LaTeX
188    text.isLaTeX = true;
189    text.content = this.processLaTeXContent(text.content);
190  }
191  
192  text.nextLine = startLine + 2;
193  return text;
194}
195
196processLaTeXContent(content) {
197  // Handle common LaTeX constructs in Xfig
198  return content
199    .replace(/$([^$]+)$/g, (match, tex) => {
200      // Inline math mode
201      return { type: 'latex-inline', content: tex };
202    })
203    .replace(/$$([^$]+)$$/g, (match, tex) => {
204      // Display math mode
205      return { type: 'latex-display', content: tex };
206    });
207}
208}`})}),"\n",(0,i.jsx)(t.h2,{children:"LaTeX Integration and Mathematical Precision"}),"\n",(0,i.jsx)(t.h3,{children:"Preserving Mathematical Notation"}),"\n",(0,i.jsxs)(a.Zp,{className:"mb-6",children:[(0,i.jsx)(a.aR,{children:(0,i.jsx)(a.ZB,{children:"LaTeX Feature Support"})}),(0,i.jsx)(a.Wu,{children:(0,i.jsxs)("div",{className:"space-y-3",children:[(0,i.jsxs)("div",{className:"flex justify-between items-center",children:[(0,i.jsx)("span",{children:"Inline equations ($...$)"}),(0,i.jsx)(o.E,{variant:"success",children:"100%"})]}),(0,i.jsxs)("div",{className:"flex justify-between items-center",children:[(0,i.jsx)("span",{children:"Display equations ($$...$$)"}),(0,i.jsx)(o.E,{variant:"success",children:"100%"})]}),(0,i.jsxs)("div",{className:"flex justify-between items-center",children:[(0,i.jsx)("span",{children:"Greek letters & symbols"}),(0,i.jsx)(o.E,{variant:"success",children:"100%"})]}),(0,i.jsxs)("div",{className:"flex justify-between items-center",children:[(0,i.jsx)("span",{children:"Matrices & arrays"}),(0,i.jsx)(o.E,{variant:"success",children:"98%"})]}),(0,i.jsxs)("div",{className:"flex justify-between items-center",children:[(0,i.jsx)("span",{children:"Custom macros"}),(0,i.jsx)(o.E,{variant:"warning",children:"95%"})]})]})})]}),"\n",(0,i.jsx)(t.h3,{children:"LaTeX to SVG Conversion"}),"\n",(0,i.jsx)("pre",{className:"bg-slate-900 text-gray-100 p-4 rounded-lg overflow-x-auto",children:(0,i.jsx)("code",{className:"language-javascript",children:`class LaTe
208XToSVG {
209constructor() {
210  this.mathjax = null;
211  this.cache = new Map();
212}
213
214async initialize() {
215  // Load MathJax for LaTeX rendering
216  this.mathjax = await window.MathJax.startup.promise;
217}
218
219async convertLaTeX(latexContent, isDisplay = false) {
220  // Check cache first
221  const cacheKey = \`\${isDisplay}:\${latexContent}\`;
222  if (this.cache.has(cacheKey)) {
223    return this.cache.get(cacheKey);
224  }
225  
226  // Convert LaTeX to SVG using MathJax
227  const math = await this.mathjax.mathml2svg(
228    this.tex2mathml(latexContent, isDisplay)
229  );
230  
231  // Extract SVG and optimize
232  const svg = math.querySelector('svg');
233  this.optimizeMathSVG(svg);
234  
235  // Cache result
236  const result = svg.outerHTML;
237  this.cache.set(cacheKey, result);
238  
239  return result;
240}
241
242tex2mathml(tex, isDisplay) {
243  // Convert TeX to MathML
244  const node = this.mathjax.tex2mml(tex, {
245    display: isDisplay,
246    em: 16,
247    ex: 8,
248    containerWidth: 80 * 16
249  });
250  
251  return node;
252}
253
254optimizeMathSVG(svg) {
255  // Remove MathJax-specific attributes
256  svg.removeAttribute('style');
257  svg.removeAttribute('focusable');
258  svg.removeAttribute('role');
259  
260  // Ensure scalability
261  if (!svg.hasAttribute('viewBox')) {
262    const width = parseFloat(svg.getAttribute('width'));
263    const height = parseFloat(svg.getAttribute('height'));
264    svg.setAttribute('viewBox', \`0 0 \${width} \${height}\`);
265  }
266  
267  // Set reasonable defaults
268  svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
269  svg.style.verticalAlign = 'middle';
270}
271}
272`})}),"\n",(0,i.jsx)(t.h2,{children:"Scientific Diagram Features"}),"\n",(0,i.jsx)(t.h3,{children:"Network Topology Diagrams"}),"\n",(0,i.jsx)("pre",{className:"bg-slate-900 text-gray-100 p-4 rounded-lg overflow-x-auto",children:(0,i.jsx)("code",{className:"language-javascript",children:`class NetworkTopologyConverter {
273convertNetworkDiagram(figObjects) {
274  const svg = {
275    nodes: [],
276    edges: [],
277    labels: [],
278    layout: null
279  };
280  
281  // Identify network components
282  figObjects.forEach(obj => {
283    if (obj.type === 'compound') {
284      // Compound objects often represent network nodes
285      const node = this.extractNetworkNode(obj);
286      if (node) svg.nodes.push(node);
287    } else if (obj.type === 'polyline' && obj.subtype === 1) {
288      // Lines often represent connections
289      const edge = this.extractNetworkEdge(obj);
290      if (edge) svg.edges.push(edge);
291    } else if (obj.type === 'text') {
292      // Labels for nodes or edges
293      svg.labels.push(this.extractLabel(obj));
294    }
295  });
296  
297  // Detect layout type
298  svg.layout = this.detectLayoutAlgorithm(svg.nodes);
299  
300  // Apply intelligent routing for edges
301  this.applyEdgeRouting(svg);
302  
303  return svg;
304}
305
306extractNetworkNode(compound) {
307  // Common patterns for network nodes in Xfig
308  const shapes = compound.objects.filter(o => 
309    o.type === 'ellipse' || 
310    (o.type === 'polyline' && o.subtype === 2) // Box
311  );
312  
313  if (shapes.length === 0) return null;
314  
315  const shape = shapes[0];
316  const labels = compound.objects.filter(o => o.type === 'text');
317  
318  return {
319    id: this.generateNodeId(shape),
320    shape: shape.type === 'ellipse' ? 'circle' : 'rect',
321    position: this.getShapeCenter(shape),
322    size: this.getShapeSize(shape),
323    label: labels.length > 0 ? labels[0].content : '',
324    style: this.convertFIGStyle(shape)
325  };
326}
327
328detectLayoutAlgorithm(nodes) {
329  // Analyze node positions to detect layout
330  const positions = nodes.map(n => n.position);
331  
332  // Check for grid layout
333  if (this.isGridLayout(positions)) {
334    return 'grid';
335  }
336  
337  // Check for hierarchical layout
338  if (this.isHierarchicalLayout(positions)) {
339    return 'hierarchical';
340  }
341  
342  // Check for circular layout
343  if (this.isCircularLayout(positions)) {
344    return 'circular';
345  }
346  
347  return 'organic';
348}
349}
350`})}),"\n",(0,i.jsx)(t.h3,{children:"Circuit Diagrams"}),"\n",(0,i.jsx)("pre",{className:"bg-slate-900 text-gray-100 p-4 rounded-lg overflow-x-auto",children:(0,i.jsx)("code",{className:"language-javascript",children:`class CircuitDiagramConverter {
351constructor() {
352  this.componentLibrary = this.loadComponentLibrary();
353  this.wireConnections = [];
354  this.components = [];
355}
356
357convertCircuitDiagram(figObjects) {
358  // Identify circuit components by pattern matching
359  figObjects.forEach(obj => {
360    const component = this.identifyComponent(obj);
361    if (component) {
362      this.components.push(component);
363    } else if (this.isWire(obj)) {
364      this.wireConnections.push(this.extractWire(obj));
365    }
366  });
367  
368  // Build netlist
369  const netlist = this.buildNetlist();
370  
371  // Generate optimized SVG
372  return this.generateCircuitSVG(netlist);
373}
374
375identifyComponent(figObject) {
376  // Pattern matching for common circuit symbols
377  if (figObject.type === 'compound') {
378    const pattern = this.extractPattern(figObject);
379    
380    // Check against component library
381    for (const [name, template] of this.componentLibrary) {
382      if (this.matchesTemplate(pattern, template)) {
383        return {
384          type: name,
385          position: this.getCompoundCenter(figObject),
386          rotation: this.getRotation(figObject),
387          value: this.extractValue(figObject),
388          reference: this.extractReference(figObject)
389        };
390      }
391    }
392  }
393  
394  return null;
395}
396
397loadComponentLibrary() {
398  return new Map([
399    ['resistor', {
400      pattern: 'polyline-zigzag',
401      terminals: 2,
402      symbol: 'R'
403    }],
404    ['capacitor', {
405      pattern: 'parallel-lines',
406      terminals: 2,
407      symbol: 'C'
408    }],
409    ['inductor', {
410      pattern: 'coil',
411      terminals: 2,
412      symbol: 'L'
413    }],
414    ['diode', {
415      pattern: 'triangle-bar',
416      terminals: 2,
417      symbol: 'D'
418    }],
419    ['transistor', {
420      pattern: 'circle-with-leads',
421      terminals: 3,
422      symbol: 'Q'
423    }]
424  ]);
425}
426}
427`})}),"\n",(0,i.jsx)(t.h2,{children:"Publication-Ready Export"}),"\n",(0,i.jsx)(t.h3,{children:"Journal-Specific Formatting"}),"\n",(0,i.jsxs)(a.Zp,{className:"mb-6",children:[(0,i.jsx)(a.aR,{children:(0,i.jsx)(a.ZB,{children:"Publication Standards Support"})}),(0,i.jsx)(a.Wu,{children:(0,i.jsxs)("div",{className:"grid grid-cols-2 gap-3 text-sm",children:[(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"font-semibold",children:"IEEE Transactions"}),(0,i.jsx)("p",{className:"text-gray-600",children:"Two-column, 600 DPI"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"font-semibold",children:"Nature/Science"}),(0,i.jsx)("p",{className:"text-gray-600",children:"Single column, RGB"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"font-semibold",children:"Physical Review"}),(0,i.jsx)("p",{className:"text-gray-600",children:"RevTeX compatible"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"font-semibold",children:"Elsevier"}),(0,i.jsx)("p",{className:"text-gray-600",children:"EPS/PDF ready"})]})]})})]}),"\n",(0,i.jsx)(t.h3,{children:"Export Options"}),"\n",(0,i.jsx)("pre",{className:"bg-slate-900 text-gray-100 p-4 rounded-lg overflow-x-auto",children:(0,i.jsx)("code",{className:"language-javascript",children:`class PublicationExporter {
428exportForJournal(svg, journalType) {
429  const specs = this.getJournalSpecs(journalType);
430  
431  // Apply journal-specific formatting
432  this.applyDimensions(svg, specs.dimensions);
433  this.applyColorSpace(svg, specs.colorSpace);
434  this.applyFontRequirements(svg, specs.fonts);
435  this.applyLineWeights(svg, specs.lineWeights);
436  
437  // Generate required formats
438  const exports = {
439    svg: svg,
440    eps: specs.requiresEPS ? this.generateEPS(svg) : null,
441    pdf: specs.requiresPDF ? this.generatePDF(svg) : null,
442    png: specs.requiresPNG ? this.generatePNG(svg, specs.dpi) : null
443  };
444  
445  return exports;
446}
447
448getJournalSpecs(journal) {
449  const specs = {
450    'ieee': {
451      dimensions: { width: '3.5in', height: 'auto' },
452      colorSpace: 'RGB',
453      fonts: ['Times', 'Helvetica', 'Symbol'],
454      lineWeights: [0.5, 1.0, 1.5, 2.0],
455      dpi: 600,
456      requiresEPS: true,
457      requiresPDF: true,
458      requiresPNG: false
459    },
460    'nature': {
461      dimensions: { width: '89mm', height: 'auto' },
462      colorSpace: 'RGB',
463      fonts: ['Arial', 'Times', 'Symbol'],
464      lineWeights: [0.25, 0.5, 1.0, 2.0],
465      dpi: 300,
466      requiresEPS: false,
467      requiresPDF: true,
468      requiresPNG: true
469    },
470    'aps': { // American Physical Society
471      dimensions: { width: '86mm', height: 'auto' },
472      colorSpace: 'Grayscale',
473      fonts: ['Computer Modern', 'Times', 'Symbol'],
474      lineWeights: [0.4, 0.8, 1.2, 1.6],
475      dpi: 600,
476      requiresEPS: true,
477      requiresPDF: false,
478      requiresPNG: false
479    }
480  };
481  
482  return specs[journal] || specs['ieee'];
483}
484}
485`})}),"\n",(0,i.jsx)(t.h2,{children:"Batch Processing for Research Groups"}),"\n",(0,i.jsx)(t.h3,{children:"Department-Wide Migration"}),"\n",(0,i.jsx)("pre",{className:"bg-slate-900 text-gray-100 p-4 rounded-lg overflow-x-auto",children:(0,i.jsx)("code",{className:"language-bash",children:`#!/bin/bash
486# Batch FIG to SVG conversion for research group
487
488FIGDIR="/shared/research/figures"
489SVGDIR="/shared/research/figures_svg"
490LOGFILE="/var/log/fig_migration.log"
491
492# Find all FIG files
493find "$FIGDIR" -name "*.fig" | while read figfile; do
494  # Extract relative path
495  relpath="\${figfile#$FIGDIR/}"
496  svgfile="$SVGDIR/\${relpath%.fig}.svg"
497  
498  # Create directory structure
499  mkdir -p "$(dirname "$svgfile")"
500  
501  # Convert with metadata preservation
502  fig2svg \
503      --input "$figfile" \
504      --output "$svgfile" \
505      --preserve-latex \
506      --embed-fonts \
507      --publication-ready \
508      --log "$LOGFILE"
509  
510  # Validate conversion
511  if validate_svg "$svgfile"; then
512      echo "✓ Converted: $relpath" >> "$LOGFILE"
513  else
514      echo "✗ Failed: $relpath" >> "$LOGFILE"
515  fi
516done
517
518# Generate migration report
519generate_report "$LOGFILE" > "$SVGDIR/migration_report.html"
520`})}),"\n",(0,i.jsx)(t.h2,{children:"Version Control Integration"}),"\n",(0,i.jsx)(t.h3,{children:"Git Hooks for FIG Files"}),"\n",(0,i.jsx)("pre",{className:"bg-slate-900 text-gray-100 p-4 rounded-lg overflow-x-auto",children:(0,i.jsx)("code",{className:"language-javascript",children:`// Pre-commit hook for automatic FIG to SVG conversion
521const { execSync } = require('child_process');
522const fs = require('fs');
523const path = require('path');
524
525function preCommitHook() {
526// Get staged FIG files
527const stagedFiles = execSync('git diff --cached --name-only --diff-filter=ACM')
528  .toString()
529  .split('
530')
531  .filter(file => file.endsWith('.fig'));
532
533stagedFiles.forEach(figFile => {
534  if (!figFile) return;
535  
536  // Generate SVG version
537  const svgFile = figFile.replace('.fig', '.svg');
538  
539  try {
540    // Convert FIG to SVG
541    execSync(\`fig2svg "\${figFile}" "\${svgFile}"\`, {
542      stdio: 'pipe'
543    });
544    
545    // Stage the SVG file
546    execSync(\`git add "\${svgFile}"\`);
547    
548    console.log(\`✓ Generated SVG for \${figFile}\`);
549  } catch (error) {
550    console.error(\`✗ Failed to convert \${figFile}: \${error.message}\`);
551    process.exit(1);
552  }
553});
554}
555
556preCommitHook();
557`})}),"\n",(0,i.jsx)(t.h2,{children:"Common Use Cases"}),"\n",(0,i.jsxs)(a.Zp,{className:"mb-6",children:[(0,i.jsx)(a.aR,{children:(0,i.jsx)(a.ZB,{children:"Research Applications"})}),(0,i.jsx)(a.Wu,{children:(0,i.jsxs)("div",{className:"space-y-3",children:[(0,i.jsxs)("div",{className:"flex items-center gap-3",children:[(0,i.jsx)(h,{className:"h-5 w-5 text-blue-500"}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"font-semibold",children:"Biological Pathways"}),(0,i.jsx)("p",{className:"text-sm text-gray-600",children:"Cell diagrams, protein interactions"})]})]}),(0,i.jsxs)("div",{className:"flex items-center gap-3",children:[(0,i.jsx)(p,{className:"h-5 w-5 text-green-500"}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"font-semibold",children:"Mathematical Proofs"}),(0,i.jsx)("p",{className:"text-sm text-gray-600",children:"Geometric constructions, graphs"})]})]}),(0,i.jsxs)("div",{className:"flex items-center gap-3",children:[(0,i.jsx)(d.A,{className:"h-5 w-5 text-purple-500"}),(0,i.jsxs)("div",{children:[(0,i.jsx)("p",{className:"font-semibold",children:"Computer Science"}),(0,i.jsx)("p",{className:"text-sm text-gray-600",children:"Algorithms, data structures, automata"})]})]})]})})]}),"\n",(0,i.jsx)(t.h2,{children:"Conclusion"}),"\n",(0,i.jsx)(t.p,{children:"FIG files represent decades of academic and scientific work. Our converter ensures that these valuable diagrams remain accessible and editable while preserving the mathematical precision and LaTeX integration that makes them essential for research publication."}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.em,{children:"Professor James Mitchell has used Xfig for scientific visualization since 1987. His work in computational physics has resulted in over 200 publications featuring FIG diagrams, now being preserved for future generations through SVG conversion."})})]})}function u(e={}){let{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(g,{...e})}):g(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.