sevgi-function 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7fd50bb171b09d5221092de41845690e2b1e8e05e62811b972306b0522f6cbea
4
- data.tar.gz: d8cff5f7b9af0492f0d0824271b4a2dc95069d2d4e82bbab012b56e0b15dc631
3
+ metadata.gz: cdb33b0136955f83cc59d68d1bf5f316debfcc20dd6f798d077c38ead8a9143b
4
+ data.tar.gz: c6500ab4812b1c6bac6dd1e61574baa2f6ca0d0344114124f39f915aa6179f7c
5
5
  SHA512:
6
- metadata.gz: ca877b117f6e9e7d7a3da866b3ac73d6120c820038e0192e0e55bb927c9b28c527f68b16ecf02fddbd69f47435fdb940214e70fe78f2f3d96e4f3a006a9732cd
7
- data.tar.gz: 5cced2a22f74bb0836f96d29de58d2d2dd1052d871bcc24bce6ffd1e59ee2760ab71e5bb2f83d36e7cf6bcdb30e3d3f0f6a4c9f7ca755bde02f2cb405948b16c
6
+ metadata.gz: 8e7eebdc538779ead3fd4e1df77e1215a97aad59774c357828a435a35633472265458ed6a2070a2cd141538570e592dac9794847513ebf9c7e812124fb73dd93
7
+ data.tar.gz: c48b0c56d4f6d92c0e9650714c363e91acc201ff599268d7f57dd5129ba450b4443dbdb5b3037d25d683bdd20d4167d0e5632333e5f5f830a9d1617ae37b2b99
data/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
3
3
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
+ ## Unreleased
7
+
8
+ ## 1.1.1 - 2026-10-29
9
+
10
+ ### Fixed
11
+
12
+ - Pass the configuration flag after the pdfcpu subcommand so A5-on-A4 export works.
13
+
14
+ ## 1.1.0 - 2026-10-29
15
+
16
+ ### Added
17
+
18
+ - `Classes` returns an element's distinct CSS class names without changing the element; `Classify` shares its attribute normalization.
19
+ - Generic document-local Style declarations with `Target`, `Param`, `Group`, and `Profiles`, and optional prepared PDF export through the native Mainz CLI.
20
+ - Backend-independent `fallback: false` for export failures and `F.executable` for executable path lookup.
21
+ - `F.path` for path validation and expansion, and `F.output_path` for default output names and directory targets.
22
+
23
+ ### Changed
24
+
25
+ - Moved Graphics XML validation into auxiliary helpers and kept built-in paper dimensions in `Paper`.
26
+ - Shared path validation between Graphics writers and Sundries exports while preserving output paths and error messages.
27
+
28
+ ### Fixed
29
+
30
+ - Stamp code placeholders in nested and shared PDF Forms, with cycle-safe resource traversal.
31
+
6
32
  ## 1.0.0 - 2026-09-16
7
33
 
8
34
  ### Added
@@ -93,6 +93,40 @@ module Sevgi
93
93
  end
94
94
  end
95
95
 
96
+ # Resolves an output path, using the default when value is nil or an existing directory.
97
+ # The default is validated only when used. This method does not create files or directories.
98
+ # @param value [String, #to_path, nil] explicit output path or directory
99
+ # @param default [String, #to_path] default output path; its basename is used for a directory target
100
+ # @param context [String] public operation named in errors
101
+ # @return [String] expanded output path
102
+ # @raise [Sevgi::ArgumentError] when a selected path/default is blank, invalid, or cannot be converted
103
+ def output_path(value, default:, context: "Output")
104
+ return path(default, context: "#{context} default") if value.nil?
105
+
106
+ output = path(value, context: "#{context} path")
107
+ return output unless ::File.directory?(output)
108
+
109
+ default = path(default, context: "#{context} default")
110
+ ::File.join(output, ::File.basename(default))
111
+ end
112
+
113
+ # Converts a non-blank path to an expanded String without requiring it to exist.
114
+ # @param value [String, #to_path] raw path value
115
+ # @param context [String] error-message subject
116
+ # @return [String] expanded path
117
+ # @raise [Sevgi::ArgumentError] when value is blank, has an invalid type, or path conversion fails
118
+ def path(value, context: "Path")
119
+ path = value.respond_to?(:to_path) ? value.to_path : value
120
+ ArgumentError.("#{context} must be a String or path-like object") unless path.is_a?(::String)
121
+ ArgumentError.("#{context} must be provided") if path.strip.empty?
122
+
123
+ ::File.expand_path(path)
124
+ rescue ::Sevgi::ArgumentError
125
+ raise
126
+ rescue ::StandardError => e
127
+ ArgumentError.("#{context} must be a String or path-like object: #{e.message}")
128
+ end
129
+
96
130
  # Adds a default extension when a path has no extension.
97
131
  # @param file [String] file path
98
132
  # @param default_extension [String] extension to append without a leading dot
@@ -8,20 +8,30 @@ module Sevgi
8
8
  # Command methods promoted to {Sevgi::F}. This module owns the public immutable {Shell::Result} value but is not
9
9
  # otherwise a consumer mixin contract.
10
10
  module Shell
11
- # Checks whether a program exists and is executable.
11
+ # Returns the absolute path of the first executable regular file, or nil.
12
12
  # @param program [Object] program name, absolute path, or relative slash-containing path
13
- # @return [Boolean] true when an executable regular file is found
13
+ # @return [String, nil] absolute executable path, preserving a selected symlink
14
14
  # @note PATH is evaluated on every call. Empty PATH segments mean the current directory.
15
- def executable?(program)
15
+ def executable(program)
16
16
  program = program.to_s
17
- return false if program.empty?
18
- return executable_file?(program) if slash_path?(program)
17
+ return if program.empty?
18
+ if slash_path?(program)
19
+ return executable_file?(program) ? ::File.expand_path(program) : nil
20
+ end
19
21
 
20
- ENV.fetch("PATH", "").split(::File::PATH_SEPARATOR, -1).any? do |dir|
21
- executable_file?(::File.join(dir.empty? ? "." : dir, program))
22
+ ENV.fetch("PATH", "").split(::File::PATH_SEPARATOR, -1).each do |dir|
23
+ path = ::File.expand_path(program, dir.empty? ? "." : dir)
24
+ return path if executable_file?(path)
22
25
  end
26
+ nil
23
27
  end
24
28
 
29
+ # Checks whether a program exists and is executable.
30
+ # @param program [Object] program name, absolute path, or relative slash-containing path
31
+ # @return [Boolean] true when an executable regular file is found
32
+ # @see #executable
33
+ def executable?(program) = !executable(program).nil?
34
+
25
35
  # Requires the first command argument to name an executable program.
26
36
  # @param args [Array<Object>] command arguments
27
37
  # @return [nil]
@@ -3,6 +3,6 @@
3
3
  module Sevgi
4
4
  module Function
5
5
  # Current version of the Sevgi function gem.
6
- VERSION = "1.0.0"
6
+ VERSION = "1.1.1"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sevgi-function
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Recai Oktaş