@@ -242,7 +242,7 @@ def parse_argv
242242 tag_fname2url = { }
243243 output_fname = nil
244244 output_format = "json"
245- warn_if_tags_no_rules = 0
245+ warn_if_tags_no_rules = false
246246
247247 i = 0
248248 while i < ARGV . count
@@ -259,7 +259,7 @@ def parse_argv
259259 when "-h"
260260 output_format = "html"
261261 when "-w"
262- warn_if_tags_no_rules = 1
262+ warn_if_tags_no_rules = true
263263 when "-d"
264264 if ( ARGV . count -i ) < 1
265265 info ( "Missing argument for -d option" )
@@ -458,25 +458,33 @@ def validate_defs_and_tags(defs, tags, warn_if_tags_no_rules)
458458 fatal ( "Need NormativeTags for tags but was passed a #{ tags . class } " ) unless tags . is_a? ( NormativeTags )
459459
460460 missing_tag_cnt = 0
461+ bad_norm_rule_name_cnt = 0
461462 unref_cnt = 0
462463 referenced_tags = { } # Key is tag name and value is any non-nil value
463464 rule_name_lengths = [ ]
464465 tag_name_lengths = [ ]
465466
466- # Detect missing tags and unreferenced tags.
467+ # Go through each normative rule definition. Look for:
468+ # - References to non-existant tags
469+ # - Normative rule names starting with "norm:" prefix (should only be for tags)
467470 defs . norm_rule_defs . each do |d |
468471 unless d . tag_refs . nil?
469472 d . tag_refs . each do |tag_ref |
470473 # Lookup tag by its name
471474 tag = tags . get_tag ( tag_ref )
472475
473476 if tag . nil?
474- missing_tag_cnt = missing_tag_cnt + 1
475- error ( "Normative rule #{ d . name } defined in file #{ d . def_filename } references non-existent tag #{ tag_ref } " )
477+ missing_tag_cnt += 1
478+ error ( "Normative rule #{ d . name } references non-existent tag #{ tag_ref } in file #{ d . def_filename } " )
476479 else
477480 referenced_tags [ tag . name ] = 1 # Any non-nil value
478481 end
479482 end
483+
484+ if d . name . start_with? ( "norm:" )
485+ bad_norm_rule_name_cnt += 1
486+ error ( "Normative rule #{ d . name } starts with \" norm:\" prefix. This prefix is only for tag names, not rule names." )
487+ end
480488 end
481489
482490 # Increment length (ensure it isn't nil first with ||=)
@@ -488,7 +496,7 @@ def validate_defs_and_tags(defs, tags, warn_if_tags_no_rules)
488496 tags . get_tags . each do |tag |
489497 if referenced_tags [ tag . name ] . nil?
490498 msg = "Tag #{ tag . name } not referenced by any normative rule. Did you forget to define a normative rule?"
491- if warn_if_tags_no_rules == 1
499+ if warn_if_tags_no_rules
492500 info ( msg )
493501 else
494502 error ( msg )
@@ -505,16 +513,22 @@ def validate_defs_and_tags(defs, tags, warn_if_tags_no_rules)
505513 error ( "#{ missing_tag_cnt } reference#{ missing_tag_cnt == 1 ? "" : "s" } to non-existing tags" )
506514 end
507515
516+ if bad_norm_rule_name_cnt > 0
517+ error ( "#{ bad_norm_rule_name_cnt } illegal normative rule name#{ bad_norm_rule_name_cnt == 1 ? "" : "s" } " )
518+ end
519+
508520 if unref_cnt > 0
509521 msg = "#{ unref_cnt } tag#{ unref_cnt == 1 ? "" : "s" } have no normative rules referencing them"
510- if warn_if_tags_no_rules == 1
522+ if warn_if_tags_no_rules
511523 info ( msg )
512524 else
513525 error ( msg )
514526 end
515527 end
516528
517- fatal ( "Exiting due to errors" ) if ( ( missing_tag_cnt > 0 ) || ( ( unref_cnt > 0 ) && ( warn_if_tags_no_rules == 0 ) ) )
529+ if ( missing_tag_cnt > 0 ) || ( bad_norm_rule_name_cnt > 0 ) || ( ( unref_cnt > 0 ) && !warn_if_tags_no_rules )
530+ fatal ( "Exiting due to errors" )
531+ end
518532
519533 # Display counts of name lengths.
520534 #info("")
@@ -536,11 +550,6 @@ def output_json(filename, normative_rules_hash)
536550 fatal ( "Need String for filename but passed a #{ filename . class } " ) unless filename . is_a? ( String )
537551 fatal ( "Need Hash<String, Array> for normative_rules_hash but passed a #{ normative_rules_hash . class } " ) unless normative_rules_hash . is_a? ( Hash )
538552
539- nr_array = normative_rules_hash [ "normative_rules" ]
540- raise "Expecting an array for key normative_rules but got an #{ nr_array . class } " unless nr_array . is_a? ( Array )
541-
542- info ( "Storing #{ nr_array . count } normative rules into file #{ filename } " )
543-
544553 # Serialize normative_rules_hash to JSON format String.
545554 # Shouldn't throw exceptions since we created the data being serialized.
546555 serialized_string = JSON . pretty_generate ( normative_rules_hash )
@@ -565,8 +574,6 @@ def output_xlsx(filename, defs, tags)
565574 fatal ( "Need NormativeRuleDefs for defs but passed a #{ defs . class } " ) unless defs . is_a? ( NormativeRuleDefs )
566575 fatal ( "Need NormativeTags for tags but passed a #{ tags . class } " ) unless tags . is_a? ( NormativeTags )
567576
568- info ( "Storing #{ defs . norm_rule_defs . count } normative rules into file #{ filename } " )
569-
570577 # Create a new Excel workbook
571578 info ( "Creating Excel workbook #{ filename } " )
572579 workbook = WriteXLSX . new ( filename )
@@ -649,8 +656,6 @@ def output_adoc(filename, defs, tags, tag_fname2url)
649656 fatal ( "Need NormativeTags for tags but passed a #{ tags . class } " ) unless tags . is_a? ( NormativeTags )
650657 fatal ( "Need Hash for tag_fname2url but passed a #{ tag_fname2url . class } " ) unless tag_fname2url . is_a? ( Hash )
651658
652- info ( "Storing #{ defs . norm_rule_defs . count } normative rules into file #{ filename } " )
653-
654659 # Organize rules by chapter name. Each hash key is chapter name. Each hash entry is an Array<NormativeRuleDef>
655660 defs_by_chapter_name = { }
656661 defs . norm_rule_defs . each do |d |
@@ -703,8 +708,6 @@ def output_html(filename, defs, tags, tag_fname2url)
703708 fatal ( "Need NormativeTags for tags but passed a #{ tags . class } " ) unless tags . is_a? ( NormativeTags )
704709 fatal ( "Need Hash for tag_fname2url but passed a #{ tag_fname2url . class } " ) unless tag_fname2url . is_a? ( Hash )
705710
706- info ( "Storing #{ defs . norm_rule_defs . count } normative rules into file #{ filename } " )
707-
708711 # Organize rules by chapter name. Each hash key is chapter name. Each hash entry is an Array<NormativeRuleDef>
709712 defs_by_chapter_name = { }
710713 chapter_names = [ ]
@@ -1010,6 +1013,18 @@ def truncate_after_newlines(text, max_newlines)
10101013 truncated_text
10111014end
10121015
1016+ def count_parameters ( defs )
1017+ raise ArgumentError , "Need NormativeRuleDefs for defs but passed a #{ defs . class } " unless defs . is_a? ( NormativeRuleDefs )
1018+
1019+ num_parameters = 0
1020+
1021+ defs . norm_rule_defs . each do |d |
1022+ num_parameters += 1 if d . kind == "parameter"
1023+ end
1024+
1025+ return num_parameters
1026+ end
1027+
10131028# Convert newlines to <br>.
10141029def html_handle_newlines ( text )
10151030 raise ArgumentError , "Expected String for text but was passed a #{ text } .class" unless text . is_a? ( String )
@@ -1035,6 +1050,9 @@ def html_handle_newlines(text)
10351050tags = load_tags ( tag_fnames )
10361051validate_defs_and_tags ( defs , tags , warn_if_tags_no_rules )
10371052
1053+ info ( "Storing #{ defs . norm_rule_defs . count } normative rules into file #{ output_fname } " )
1054+ info ( "Includes #{ count_parameters ( defs ) } parameters" )
1055+
10381056case output_format
10391057when "json"
10401058 normative_rules_hash = create_normative_rules_hash ( defs , tags , tag_fname2url )
0 commit comments