@@ -85,10 +85,15 @@ def each(&block)
8585 end
8686
8787 ##
88- # A hash of all vocabularies by prefix showing relevant URI and associated vocabulary Class Name
88+ # A hash of all vocabularies by prefix showing relevant URI and
89+ # associated vocabulary Class Name
90+ #
8991 # @return [Hash{Symbol => Hash{Symbol => String}}]
9092 def vocab_map
91- VOCABS
93+ # Create an initial duplicate of RDF::VOCABS. We want to
94+ # ensure the hash itself is modifiable but the values are
95+ # frozen.
96+ @vocab_map ||= RDF ::VOCABS . transform_values ( &:freeze )
9297 end
9398
9499 ##
@@ -100,6 +105,36 @@ def from_sym(sym)
100105 RDF . const_get ( sym . to_sym )
101106 end
102107
108+ ##
109+ # Register a vocabulary for internal prefix lookups. Parameters
110+ # of interest include `:uri`, `:class_name`, `:source`, and `:skip`.
111+ #
112+ # @param prefix [Symbol] the prefix to use
113+ # @param vocab [String, Class] either the URI or the vocab class
114+ # @param params [Hash{Symbol => String}] Relevant parameters
115+ # @return [Hash] The parameter hash, but frozen
116+ def register ( prefix , vocab , **params )
117+ # check the input
118+ raise ArgumentError , "#{ prefix } must be symbol-able" unless
119+ [ String , Symbol ] . any? { |c | prefix . is_a? c }
120+
121+ # note an explicit uri: param overrides
122+ case vocab
123+ when String then params [ :uri ] ||= vocab
124+ when Class
125+ raise ArgumentError , 'vocab must be an RDF::(Strict)Vocabulary' unless
126+ vocab . ancestors . include? RDF ::Vocabulary
127+ params [ :class ] = vocab
128+ params [ :uri ] ||= vocab . to_uri . to_s
129+ end
130+
131+ # fill in the class name
132+ params [ :class_name ] ||= prefix . to_s . upcase
133+
134+ # now freeze and assign
135+ vocab_map [ prefix . to_s . to_sym ] = params . freeze
136+ end
137+
103138 ##
104139 # Limits iteration over vocabularies to just those selected
105140 #
@@ -347,7 +382,8 @@ def expand_pname(pname)
347382 if prefix == "rdf"
348383 RDF [ suffix ]
349384 elsif vocab_detail = RDF ::Vocabulary . vocab_map [ prefix . to_sym ]
350- vocab = RDF ::Vocabulary . from_sym ( vocab_detail [ :class_name ] )
385+ vocab = vocab_detail [ :class ] ||
386+ RDF ::Vocabulary . from_sym ( vocab_detail [ :class_name ] )
351387 suffix . to_s . empty? ? vocab . to_uri : vocab [ suffix ]
352388 else
353389 ( RDF ::Vocabulary . find_term ( pname ) rescue nil ) || RDF ::URI ( pname , validate : true )
0 commit comments