Все требования реализованы без полного покрытия модульными тестами. (#3)
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				drawio-export/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	drawio-export/pipeline/head This commit looks good
				
			PR closes #1 Reviewed-on: #3
This commit is contained in:
		
							parent
							
								
									0d6f42f425
								
							
						
					
					
						commit
						78624641e4
					
				| @ -1,7 +1,31 @@ | ||||
| package main | ||||
| 
 | ||||
| import "fmt" | ||||
| import ( | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 
 | ||||
| 	"git.mousesoft.ru/ms/drawio-exporter/pkg/drawio" | ||||
| ) | ||||
| 
 | ||||
| var version string // Версия приложения | ||||
| 
 | ||||
| func main() { | ||||
| 	fmt.Println("Draw.io Exporter") | ||||
| 	flag.Parse() | ||||
| 	if flagHelp { | ||||
| 		flag.Usage() | ||||
| 		os.Exit(0) | ||||
| 	} | ||||
| 	if flagVersion { | ||||
| 		fmt.Println("Draw.io Export cli util", version) | ||||
| 		os.Exit(0) | ||||
| 	} | ||||
| 	if flag.NArg() < 1 { | ||||
| 		flag.Usage() | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
| 	exporter := drawio.NewWithOptions(&opts) | ||||
| 	if err := exporter.Export(flag.Args()...); err != nil { | ||||
| 		fmt.Fprintln(os.Stderr, "Error:", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										75
									
								
								cmd/drawio-export/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								cmd/drawio-export/options.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"flag" | ||||
| 
 | ||||
| 	"git.mousesoft.ru/ms/drawio-exporter/pkg/drawio" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	flagHelp    bool               // Вывести справку о приложении и выйти | ||||
| 	flagVersion bool               // Вывести информацию о версии приложения и выйти | ||||
| 	opts        = drawio.Options{} // Аргументы командной строки приложения | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	// version | ||||
| 	flag.BoolVar(&flagVersion, "V", false, "Prints version information") | ||||
| 	flag.BoolVar(&flagVersion, "version", false, "Prints version information") | ||||
| 	// Application | ||||
| 	flag.StringVar(&opts.Application, "A", "", "Draw.io Desktop Application") | ||||
| 	flag.StringVar(&opts.Application, "application", "", "Draw.io Desktop Application") | ||||
| 	// Output | ||||
| 	flag.StringVar(&opts.Output, "o", "", "Exported folder name [default: export]") | ||||
| 	flag.StringVar(&opts.Output, "output", "", "Exported folder name [default: export]") | ||||
| 	// Format | ||||
| 	flag.Var(&opts.Format, "f", | ||||
| 		"Exported format [default: pdf]  [possible values: pdf, png, jpg, svg, vsdx, xml]") | ||||
| 	flag.Var(&opts.Format, "format", | ||||
| 		"Exported format [default: pdf]  [possible values: pdf, png, jpg, svg, vsdx, xml]") | ||||
| 	// Recursive | ||||
| 	flag.BoolVar(&opts.Recursive, "r", false, | ||||
| 		"For a folder input, recursively convert all files in sub-folders also") | ||||
| 	flag.BoolVar(&opts.Recursive, "recursive", false, | ||||
| 		"For a folder input, recursively convert all files in sub-folders also") | ||||
| 	// RemovePageSuffix | ||||
| 	flag.BoolVar(&opts.RemovePageSuffix, "remove-page-suffix", false, | ||||
| 		"Remove page suffix when possible (in case of single page file") | ||||
| 	// Quality | ||||
| 	flag.UintVar(&opts.Quality, "q", 0, "Output image quality for JPEG [default: 90]") | ||||
| 	flag.UintVar(&opts.Quality, "quality", 0, "Output image quality for JPEG [default: 90]") | ||||
| 	// Transparent | ||||
| 	flag.BoolVar(&opts.Transparent, "t", false, "Set transparent background for PNG") | ||||
| 	flag.BoolVar(&opts.Transparent, "transparent", false, "Set transparent background for PNG") | ||||
| 	// EmbedDiagram | ||||
| 	flag.BoolVar(&opts.EmbedDiagram, "e", false, | ||||
| 		"Includes a copy of the diagram for PDF, PNG, or SVG") | ||||
| 	flag.BoolVar(&opts.EmbedDiagram, "embed-diagram", false, | ||||
| 		"Includes a copy of the diagram for PDF, PNG, or SVG") | ||||
| 	// EmbedSvgImages | ||||
| 	flag.BoolVar(&opts.EmbedSvgImages, "embed-svg-images", false, "Embed Images in SVG file") | ||||
| 	// Border | ||||
| 	flag.UintVar(&opts.Border, "b", 0, | ||||
| 		"Sets the border width around the diagram [default: 0]") | ||||
| 	flag.UintVar(&opts.Border, "border", 0, | ||||
| 		"Sets the border width around the diagram [default: 0]") | ||||
| 	// Scale | ||||
| 	flag.UintVar(&opts.Scale, "s", 0, "Scales the diagram size") | ||||
| 	flag.UintVar(&opts.Scale, "scale", 0, "Scales the diagram size") | ||||
| 	// Width | ||||
| 	flag.UintVar(&opts.Width, "width", 0, | ||||
| 		"Fits the generated image/pdf into the specified width, preserves aspect ratio") | ||||
| 	// Height | ||||
| 	flag.UintVar(&opts.Height, "height", 0, | ||||
| 		"Fits the generated image/pdf into the specified height, preserves aspect ratio") | ||||
| 	// Crop | ||||
| 	flag.BoolVar(&opts.Crop, "crop", false, "Crops PDF to diagram size") | ||||
| 	// Uncompressed | ||||
| 	flag.BoolVar(&opts.Uncompressed, "u", false, "Uncompressed XML output") | ||||
| 	flag.BoolVar(&opts.Uncompressed, "uncompressed", false, "Uncompressed XML output") | ||||
| 	// EnablePlugins | ||||
| 	flag.BoolVar(&opts.EnablePlugins, "enable-plugins", false, "Enable Plugins") | ||||
| 	// help | ||||
| 	flag.BoolVar(&flagHelp, "h", false, "Prints help information") | ||||
| 	flag.BoolVar(&flagHelp, "help", false, "Prints help information") | ||||
| } | ||||
| @ -2,12 +2,67 @@ package drawio | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/fs" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	xmlparser "github.com/tamerh/xml-stream-parser" | ||||
| ) | ||||
| 
 | ||||
| // Создать нового экспортёра диаграмм | ||||
| func New(opt ...Option) Exporter { | ||||
| 	options := &Options{ | ||||
| 		Application: "drawio", | ||||
| 		Output:      "export", | ||||
| 		Format:      Format("pdf"), | ||||
| 	} | ||||
| 	for _, opt := range opt { | ||||
| 		opt.apply(options) | ||||
| 	} | ||||
| 	return NewWithOptions(options) | ||||
| } | ||||
| 
 | ||||
| // Создать нового экспортёра с параметрами | ||||
| func NewWithOptions(opts *Options) Exporter { | ||||
| 	return Exporter{opts: opts} | ||||
| } | ||||
| 
 | ||||
| // Экспортёр диаграмм | ||||
| type Exporter struct { | ||||
| 	opts *Options | ||||
| } | ||||
| 
 | ||||
| // Экспорт диаграмм из указанный файлов или папок | ||||
| func (exp Exporter) Export(fileOrDir ...string) error { | ||||
| 	var ( | ||||
| 		err  error | ||||
| 		errs = []error{} | ||||
| 		args = exp.opts.Args() | ||||
| 		info fs.FileInfo | ||||
| 	) | ||||
| 	for _, item := range fileOrDir { | ||||
| 		if info, err = os.Stat(item); err != nil { | ||||
| 			errs = append(errs, err) | ||||
| 			continue | ||||
| 		} | ||||
| 		if info.IsDir() { | ||||
| 			err = exp.exportDir(item, args) | ||||
| 		} else { | ||||
| 			err = exp.exportFile(item, args) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err) | ||||
| 		} | ||||
| 	} | ||||
| 	return errors.Join(errs...) | ||||
| } | ||||
| 
 | ||||
| // Разбирает данные и возвращает срез имён диаграмм в них | ||||
| func Diagrams(reader io.Reader) ([]string, error) { | ||||
| 	var ( | ||||
| @ -21,7 +76,6 @@ func Diagrams(reader io.Reader) ([]string, error) { | ||||
| 		if xml.Err != nil { | ||||
| 			return result, xml.Err | ||||
| 		} | ||||
| 		fmt.Println(xml.Name) | ||||
| 		if items, ok := xml.Childs["diagram"]; ok { | ||||
| 			for _, item := range items { | ||||
| 				result = append(result, item.Attrs["name"]) | ||||
| @ -30,3 +84,72 @@ func Diagrams(reader io.Reader) ([]string, error) { | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
| 
 | ||||
| // Экспорт диаграмм из всех файлов в папке | ||||
| func (exp Exporter) exportDir(dirPath string, args []string, subDir ...string) error { | ||||
| 	var ( | ||||
| 		entries []fs.DirEntry | ||||
| 		err     error | ||||
| 		errs    []error | ||||
| 	) | ||||
| 	if entries, err = os.ReadDir(dirPath); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for _, entry := range entries { | ||||
| 		name := entry.Name() | ||||
| 		outDir := make([]string, len(subDir), len(subDir)+1) | ||||
| 		outDir = append(outDir, name) | ||||
| 		if entry.IsDir() && exp.opts.Recursive { | ||||
| 			err = exp.exportDir(path.Join(dirPath, name), args, outDir...) | ||||
| 		} else { | ||||
| 			err = exp.exportFile(path.Join(dirPath, name), args, outDir...) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err) | ||||
| 		} | ||||
| 	} | ||||
| 	return errors.Join(errs...) | ||||
| } | ||||
| 
 | ||||
| // Экспорт файла с диаграммами | ||||
| func (exp Exporter) exportFile(filePath string, args []string, subDir ...string) error { | ||||
| 	var ( | ||||
| 		file     *os.File | ||||
| 		diagrams []string | ||||
| 		err      error | ||||
| 	) | ||||
| 	if file, err = os.Open(filePath); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer file.Close() | ||||
| 	if diagrams, err = Diagrams(file); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	outDirs := make([]string, 1, len(subDir)+1) | ||||
| 	outDirs[0] = exp.opts.Output | ||||
| 	outDirs = append(outDirs, subDir...) | ||||
| 	output := path.Join(outDirs...) | ||||
| 	errs := []error{} | ||||
| 	for i, name := range diagrams { | ||||
| 		outName := strings.TrimSuffix(path.Base(filePath), path.Ext(filePath)) | ||||
| 		if !exp.opts.RemovePageSuffix || len(diagrams) > 1 { | ||||
| 			outName += "-" + name | ||||
| 		} | ||||
| 		outName += exp.opts.OutExt() | ||||
| 		drawioArgs := make([]string, len(args), len(args)+4) | ||||
| 		copy(drawioArgs, args) | ||||
| 		drawioArgs = append(drawioArgs, | ||||
| 			"--page-index", strconv.Itoa(i), | ||||
| 			"--output", path.Join(output, outName), | ||||
| 			"--export", filePath, | ||||
| 		) | ||||
| 		cmd := exec.Command(exp.opts.App(), drawioArgs...) | ||||
| 		cmd.Stdout = os.Stdout | ||||
| 		cmd.Stderr = os.Stderr | ||||
| 		fmt.Println("Run command:", cmd.Path, cmd.Args) | ||||
| 		if err = cmd.Run(); err != nil { | ||||
| 			errs = append(errs, err) | ||||
| 		} | ||||
| 	} | ||||
| 	return errors.Join(errs...) | ||||
| } | ||||
|  | ||||
							
								
								
									
										350
									
								
								pkg/drawio/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								pkg/drawio/options.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,350 @@ | ||||
| package drawio | ||||
| 
 | ||||
| import ( | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| ) | ||||
| 
 | ||||
| // Интерфейс параметра экспортёра диаграмм | ||||
| type Option interface { | ||||
| 	apply(opts *Options) // Применить параметр к хранилищу параметров | ||||
| } | ||||
| 
 | ||||
| // Ошибка "неподдерживаемый формат" | ||||
| type ErrUnsupportedFormat struct { | ||||
| 	Format string | ||||
| } | ||||
| 
 | ||||
| // Описание ошибки | ||||
| func (e ErrUnsupportedFormat) Error() string { | ||||
| 	return fmt.Sprintf("unsupported format: '%s'", e.Format) | ||||
| } | ||||
| 
 | ||||
| var _ error = (*ErrUnsupportedFormat)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| type Format string // Формат экспортированного файла | ||||
| 
 | ||||
| // Строковое представление формата | ||||
| func (f Format) String() string { | ||||
| 	return string(f) | ||||
| } | ||||
| 
 | ||||
| // Загрузка формата из строки | ||||
| func (f *Format) Set(str string) error { | ||||
| 	for _, fmt := range SupportedFormats() { | ||||
| 		if str == string(fmt) { | ||||
| 			*f = Format(str) | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
| 	return &ErrUnsupportedFormat{str} | ||||
| } | ||||
| 
 | ||||
| var _ flag.Value = (*Format)(nil) // Поверка реализации интерфейса | ||||
| 
 | ||||
| // Расширение файла заданного формата | ||||
| func (f Format) ext() string { | ||||
| 	return "." + string(f) | ||||
| } | ||||
| 
 | ||||
| // Параметры экспортёра диаграмм | ||||
| type Options struct { | ||||
| 	Application      string // Путь к приложению drawio | ||||
| 	Output           string // Путь к папке с экспортированными файлами | ||||
| 	Format           Format // Формат экспортированных файлов | ||||
| 	Recursive        bool   // Рекурсивно сканировать вложенные папки с файлами | ||||
| 	RemovePageSuffix bool   // Удалять суффикс страницы, если это возможно | ||||
| 	Quality          uint   // Качество экспортированного изображения (только для JPEG) | ||||
| 	Transparent      bool   // Прозрачный фона для PNG | ||||
| 	// Включать копию диаграммы в экспортированный файл для PDF, PNG и SVG | ||||
| 	EmbedDiagram   bool | ||||
| 	EmbedSvgImages bool // Встраивать изображения в файл формата SVG | ||||
| 	Border         uint // Ширина рамки вокруг диаграмм | ||||
| 	Scale          uint // Масштаб в процентах размера экспортированных диаграмм | ||||
| 	Width          uint // Ширина экспортированной диаграммы с сохранением масштаба | ||||
| 	Height         uint // Высота экспортированной диаграммы с сохранением масштаба | ||||
| 	Crop           bool // Обрезать результирующий PDF до размера диаграммы | ||||
| 	Uncompressed   bool // Выводить несжатый XML | ||||
| 	EnablePlugins  bool // Включить подключаемые модули | ||||
| } | ||||
| 
 | ||||
| // Путь к приложению drawio | ||||
| func (opts Options) App() string { | ||||
| 	app := opts.Application | ||||
| 	if len(app) == 0 { | ||||
| 		app = "drawio" | ||||
| 	} | ||||
| 	return app | ||||
| } | ||||
| 
 | ||||
| // Путь к папке с экспортированными файлами | ||||
| func (opts Options) OutDir() string { | ||||
| 	out := opts.Output | ||||
| 	if len(out) == 0 { | ||||
| 		out = "export" | ||||
| 	} | ||||
| 	return out | ||||
| } | ||||
| 
 | ||||
| // Расширение экспортированных файлов | ||||
| func (opts Options) OutExt() string { | ||||
| 	fmt := opts.Format | ||||
| 	if len(fmt) == 0 { | ||||
| 		fmt = Format("pdf") | ||||
| 	} | ||||
| 	return fmt.ext() | ||||
| } | ||||
| 
 | ||||
| // Формирование аргументов командной строки | ||||
| func (opts Options) Args() []string { | ||||
| 	args := []string{} | ||||
| 	if len(opts.Format) > 0 { | ||||
| 		args = append(args, "--format", string(opts.Format)) | ||||
| 	} | ||||
| 	if opts.Quality != 0 { | ||||
| 		args = append(args, "--quality", strconv.Itoa(int(opts.Quality))) | ||||
| 	} | ||||
| 	if opts.Transparent { | ||||
| 		args = append(args, "--transparent") | ||||
| 	} | ||||
| 	if opts.EmbedDiagram { | ||||
| 		args = append(args, "--embed-diagram") | ||||
| 	} | ||||
| 	if opts.EmbedSvgImages { | ||||
| 		args = append(args, "--embed-svg-images") | ||||
| 	} | ||||
| 	if opts.Border != 0 { | ||||
| 		args = append(args, "--border", strconv.Itoa(int(opts.Border))) | ||||
| 	} | ||||
| 	if opts.Scale != 0 { | ||||
| 		args = append(args, "--scale", strconv.Itoa(int(opts.Scale))) | ||||
| 	} | ||||
| 	if opts.Width != 0 { | ||||
| 		args = append(args, "--width", strconv.Itoa(int(opts.Width))) | ||||
| 	} | ||||
| 	if opts.Height != 0 { | ||||
| 		args = append(args, "--height", strconv.Itoa(int(opts.Height))) | ||||
| 	} | ||||
| 	if opts.Crop { | ||||
| 		args = append(args, "--crop") | ||||
| 	} | ||||
| 	if opts.Uncompressed { | ||||
| 		args = append(args, "--uncompressed") | ||||
| 	} | ||||
| 	if opts.EnablePlugins { | ||||
| 		args = append(args, "--enable-plugins") | ||||
| 	} | ||||
| 	return args | ||||
| } | ||||
| 
 | ||||
| // Путь к приложению drawio | ||||
| func WithAppPath(path string) Option { | ||||
| 	return optionApplication(path) | ||||
| } | ||||
| 
 | ||||
| type optionApplication string | ||||
| 
 | ||||
| var _ Option = (*optionApplication)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionApplication) apply(opts *Options) { | ||||
| 	opts.Application = string(opt) | ||||
| } | ||||
| 
 | ||||
| // Путь к папке с экспортированными файлами | ||||
| func WithOutput(path string) Option { | ||||
| 	return optionOutput(path) | ||||
| } | ||||
| 
 | ||||
| type optionOutput string | ||||
| 
 | ||||
| var _ Option = (*optionOutput)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionOutput) apply(opts *Options) { | ||||
| 	opts.Output = string(opt) | ||||
| } | ||||
| 
 | ||||
| // Формат экспортированных файлов | ||||
| func WithFormat(format Format) Option { | ||||
| 	return format | ||||
| } | ||||
| 
 | ||||
| var _ Option = (*Format)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt Format) apply(opts *Options) { | ||||
| 	opts.Format = opt | ||||
| } | ||||
| 
 | ||||
| // Рекурсивно сканировать вложенные папки с файлами | ||||
| func WithRecursive() Option { | ||||
| 	return optionRecursive{} | ||||
| } | ||||
| 
 | ||||
| type optionRecursive struct{} | ||||
| 
 | ||||
| var _ Option = optionRecursive{} // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionRecursive) apply(opts *Options) { | ||||
| 	opts.Recursive = true | ||||
| } | ||||
| 
 | ||||
| // Удалять суффикс страницы, если это возможно | ||||
| func WithRemovePageSuffix() Option { | ||||
| 	return optionRemovePageSuffix{} | ||||
| } | ||||
| 
 | ||||
| type optionRemovePageSuffix struct{} | ||||
| 
 | ||||
| var _ Option = optionRemovePageSuffix{} // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionRemovePageSuffix) apply(opts *Options) { | ||||
| 	opts.RemovePageSuffix = true | ||||
| } | ||||
| 
 | ||||
| // Качество экспортированного изображения (только для JPEG) | ||||
| func WithQuality(q int) Option { | ||||
| 	return optionQuality(q) | ||||
| } | ||||
| 
 | ||||
| type optionQuality uint | ||||
| 
 | ||||
| var _ Option = (*optionQuality)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionQuality) apply(opts *Options) { | ||||
| 	opts.Quality = uint(opt) | ||||
| } | ||||
| 
 | ||||
| // Прозрачный фона для PNG | ||||
| func WithTransparent() Option { | ||||
| 	return optionTransparent{} | ||||
| } | ||||
| 
 | ||||
| type optionTransparent struct{} | ||||
| 
 | ||||
| var _ Option = optionTransparent{} // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionTransparent) apply(opts *Options) { | ||||
| 	opts.Transparent = true | ||||
| } | ||||
| 
 | ||||
| // Включать копию диаграммы в экспортированный файл для PDF, PNG и SVG | ||||
| func WithEmbedDiagram() Option { | ||||
| 	return optionEmbedDiagram{} | ||||
| } | ||||
| 
 | ||||
| type optionEmbedDiagram struct{} | ||||
| 
 | ||||
| var _ Option = optionEmbedDiagram{} // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionEmbedDiagram) apply(opts *Options) { | ||||
| 	opts.EmbedDiagram = true | ||||
| } | ||||
| 
 | ||||
| // Встраивать изображения в файл формата SVG | ||||
| func WithEmbedSvgImages() Option { | ||||
| 	return optionEmbedSvgImages{} | ||||
| } | ||||
| 
 | ||||
| type optionEmbedSvgImages struct{} | ||||
| 
 | ||||
| var _ Option = optionEmbedSvgImages{} // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionEmbedSvgImages) apply(opts *Options) { | ||||
| 	opts.EmbedSvgImages = true | ||||
| } | ||||
| 
 | ||||
| // Ширина рамки вокруг диаграмм | ||||
| func WithBorder(border int) Option { | ||||
| 	return optionBorder(border) | ||||
| } | ||||
| 
 | ||||
| type optionBorder uint | ||||
| 
 | ||||
| var _ Option = (*optionBorder)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionBorder) apply(opts *Options) { | ||||
| 	opts.Border = uint(opt) | ||||
| } | ||||
| 
 | ||||
| // Масштаб в процентах размера экспортированных диаграмм | ||||
| func WithScale(scale int) Option { | ||||
| 	return optionScale(scale) | ||||
| } | ||||
| 
 | ||||
| type optionScale uint | ||||
| 
 | ||||
| var _ Option = (*optionScale)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionScale) apply(opts *Options) { | ||||
| 	opts.Scale = uint(opt) | ||||
| } | ||||
| 
 | ||||
| // Ширина экспортированной диаграммы с сохранением масштаба | ||||
| func WithWidth(width int) Option { | ||||
| 	return optionWidth(width) | ||||
| } | ||||
| 
 | ||||
| type optionWidth uint | ||||
| 
 | ||||
| var _ Option = (*optionWidth)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionWidth) apply(opts *Options) { | ||||
| 	opts.Width = uint(opt) | ||||
| } | ||||
| 
 | ||||
| // Высота экспортированной диаграммы с сохранением масштаба | ||||
| func WithHeight(height int) Option { | ||||
| 	return optionHeight(height) | ||||
| } | ||||
| 
 | ||||
| type optionHeight uint | ||||
| 
 | ||||
| var _ Option = (*optionHeight)(nil) // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionHeight) apply(opts *Options) { | ||||
| 	opts.Height = uint(opt) | ||||
| } | ||||
| 
 | ||||
| // Обрезать результирующий PDF до размера диаграммы | ||||
| func WithCrop() Option { | ||||
| 	return optionCrop{} | ||||
| } | ||||
| 
 | ||||
| type optionCrop struct{} | ||||
| 
 | ||||
| var _ Option = optionCrop{} // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionCrop) apply(opts *Options) { | ||||
| 	opts.Crop = true | ||||
| } | ||||
| 
 | ||||
| // Выводить несжатый XML | ||||
| func WithUncompressed() Option { | ||||
| 	return optionUncompressed{} | ||||
| } | ||||
| 
 | ||||
| type optionUncompressed struct{} | ||||
| 
 | ||||
| var _ Option = optionUncompressed{} // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionUncompressed) apply(opts *Options) { | ||||
| 	opts.Uncompressed = true | ||||
| } | ||||
| 
 | ||||
| // Включить подключаемые модули | ||||
| func WithEnablePlugins() Option { | ||||
| 	return optionEnablePlugins{} | ||||
| } | ||||
| 
 | ||||
| type optionEnablePlugins struct{} | ||||
| 
 | ||||
| var _ Option = optionEnablePlugins{} // Проверка реализации интерфейса | ||||
| 
 | ||||
| func (opt optionEnablePlugins) apply(opts *Options) { | ||||
| 	opts.EnablePlugins = true | ||||
| } | ||||
| 
 | ||||
| // Список всех поддерживаемых форматов экспорта | ||||
| func SupportedFormats() []Format { | ||||
| 	return []Format{"pdf", "png", "jpg", "svg", "vsdx", "xml"} | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user