From e79795adc04262967619d16783a8d8737773d08e Mon Sep 17 00:00:00 2001 From: James Ball Date: Sat, 1 Nov 2025 09:23:12 -0700 Subject: [PATCH] Fixes and unit-level tests for issues 106, 107, & 108 Signed-off-by: James Ball --- Makefile | 62 +++++++++++------- tests/norm-rule/expected/test-norm-rules.json | 12 ++++ tests/norm-rule/expected/test-norm-rules.xlsx | Bin 7056 -> 7188 bytes tests/norm-rule/expected/test-norm-tags.json | 4 +- tests/norm-rule/test.adoc | 4 ++ tests/norm-rule/test.yaml | 2 + tests/tags/duplicate.adoc | 4 +- tools/create_normative_rules.rb | 57 +++++++++++----- 8 files changed, 101 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 6106ad5..f2f68b0 100644 --- a/Makefile +++ b/Makefile @@ -28,22 +28,24 @@ TAGS_BACKEND := tags.rb CREATE_NORM_RULE_TOOL := create_normative_rules.rb # Input and output file names -GOOD_TEST_ADOC_INPUT_FNAME := test.adoc -BAD_TEST_ADOC_INPUT_FNAME := duplicate.adoc -GOOD_NORM_TAGS_OUTPUT_FNAME := test-norm-tags.json -BAD_NORM_TAGS_OUTPUT_FNAME := bad-tags.json +MAIN_TEST_ADOC_INPUT_FNAME := test.adoc +DUPLICATE_TEST_ADOC_INPUT_FNAME := duplicate.adoc +MAIN_NORM_TAGS_OUTPUT_FNAME := test-norm-tags.json +DUPLICATE_NORM_TAGS_OUTPUT_FNAME := duplicate-tags.json NORM_RULE_JSON_OUTPUT_FNAME := test-norm-rules.json NORM_RULE_XLSX_OUTPUT_FNAME := test-norm-rules.xlsx +NORM_RULE_TAGS_NO_RULES_OUTPUT_FNAME := test-norm-rules_tags_no_rules.json # Built output files -BUILT_NORM_TAGS_GOOD := $(BUILD_DIR)/$(GOOD_NORM_TAGS_OUTPUT_FNAME) -BUILT_NORM_TAGS_BAD := $(BUILD_DIR)/$(BAD_NORM_TAGS_OUTPUT_FNAME) +BUILT_NORM_TAGS_MAIN := $(BUILD_DIR)/$(MAIN_NORM_TAGS_OUTPUT_FNAME) +BUILT_NORM_TAGS_DUPLICATE := $(BUILD_DIR)/$(DUPLICATE_NORM_TAGS_OUTPUT_FNAME) BUILT_NORM_RULES_JSON := $(BUILD_DIR)/$(NORM_RULE_JSON_OUTPUT_FNAME) BUILT_NORM_RULES_XLSX := $(BUILD_DIR)/$(NORM_RULE_XLSX_OUTPUT_FNAME) +BUILT_NORM_RULES_TAGS_NO_RULES := $(BUILD_DIR)/$(NORM_RULE_TAGS_NO_RULES_OUTPUT_FNAME) # Copies of expected output files. # Use make target "update-expected" to update from build dir contents. -EXPECTED_NORM_TAGS := $(NORM_RULE_EXPECTED_DIR)/$(GOOD_NORM_TAGS_OUTPUT_FNAME) +EXPECTED_NORM_TAGS := $(NORM_RULE_EXPECTED_DIR)/$(MAIN_NORM_TAGS_OUTPUT_FNAME) EXPECTED_NORM_RULES_JSON := $(NORM_RULE_EXPECTED_DIR)/$(NORM_RULE_JSON_OUTPUT_FNAME) EXPECTED_NORM_RULES_XLSX := $(NORM_RULE_EXPECTED_DIR)/$(NORM_RULE_XLSX_OUTPUT_FNAME) @@ -51,7 +53,7 @@ EXPECTED_NORM_RULES_XLSX := $(NORM_RULE_EXPECTED_DIR)/$(NORM_RULE_XLSX_OUTPUT_FN NORM_RULE_DEF_FILES := $(wildcard $(NORM_RULE_DEF_DIR)/*.yaml) # Add -t to each normative tag input filename and add prefix of "/" to make into absolute pathname. -NORM_TAG_FILE_ARGS := $(foreach relative_pname,$(BUILT_NORM_TAGS_GOOD),-t /$(relative_pname)) +NORM_TAG_FILE_ARGS := $(foreach relative_pname,$(BUILT_NORM_TAGS_MAIN),-t /$(relative_pname)) # Add -d to each normative rule definition filename NORM_RULE_DEF_ARGS := $(foreach relative_pname,$(NORM_RULE_DEF_FILES),-d $(relative_pname)) @@ -122,18 +124,19 @@ test: build-tests compare-tests # Build tests .PHONY: build-tests build-test-tags build-test-norm-rules-json build-test-norm-rules-xlsx -build-tests: build-test-tags build-test-norm-rules-json build-test-norm-rules-xlsx -build-test-tags: $(BUILT_NORM_TAGS_GOOD) $(BUILT_NORM_TAGS_BAD) +build-tests: build-test-tags build-test-norm-rules-json build-test-norm-rules-xlsx build-test-tags-without-rules +build-test-tags: $(BUILT_NORM_TAGS_MAIN) $(BUILT_NORM_TAGS_DUPLICATE) build-test-norm-rules-json: $(BUILT_NORM_RULES_JSON) build-test-norm-rules-xlsx: $(BUILT_NORM_RULES_XLSX) +build-test-tags-without-rules: $(BUILT_NORM_RULES_TAGS_NO_RULES) # Compare tests against expected .PHONY: compare-tests compare-tests: compare-test-tags compare-test-norm-rules-json -compare-test-tags: $(EXPECTED_NORM_TAGS) $(BUILT_NORM_TAGS_GOOD) +compare-test-tags: $(EXPECTED_NORM_TAGS) $(BUILT_NORM_TAGS_MAIN) @echo "CHECKING BUILT TAGS AGAINST EXPECTED TAGS" - diff $(EXPECTED_NORM_TAGS) $(BUILT_NORM_TAGS_GOOD) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) + diff $(EXPECTED_NORM_TAGS) $(BUILT_NORM_TAGS_MAIN) && echo "diff PASSED" || (echo "diff FAILED"; exit 1) compare-test-norm-rules: $(EXPECTED_NORM_RULES) $(BUILT_NORM_RULES) @@ -145,8 +148,8 @@ compare-test-norm-rules-json: $(EXPECTED_NORM_RULES_JSON) $(BUILT_NORM_RULES_JSO .PHONY: update-expected update-expected: update-test-tags update-test-norm-rules-json update-test-norm-rules-xlsx -update-test-tags: $(BUILT_NORM_TAGS_GOOD) - cp -f $(BUILT_NORM_TAGS_GOOD) $(EXPECTED_NORM_TAGS) +update-test-tags: $(BUILT_NORM_TAGS_MAIN) + cp -f $(BUILT_NORM_TAGS_MAIN) $(EXPECTED_NORM_TAGS) update-test-norm-rules-json: $(BUILT_NORM_RULES_JSON) cp -f $(BUILT_NORM_RULES_JSON) $(EXPECTED_NORM_RULES_JSON) @@ -154,33 +157,42 @@ update-test-norm-rules-json: $(BUILT_NORM_RULES_JSON) update-test-norm-rules-xlsx: $(BUILT_NORM_RULES_XLSX) cp -f $(BUILT_NORM_RULES_XLSX) $(EXPECTED_NORM_RULES_XLSX) -# Build normative tags with good adoc input -$(BUILT_NORM_TAGS_GOOD): $(NORM_RULE_TESTS_DIR)/$(GOOD_TEST_ADOC_INPUT_FNAME) $(CONVERTERS_DIR)/$(TAGS_BACKEND) +# Build normative tags with main adoc input +$(BUILT_NORM_TAGS_MAIN): $(NORM_RULE_TESTS_DIR)/$(MAIN_TEST_ADOC_INPUT_FNAME) $(CONVERTERS_DIR)/$(TAGS_BACKEND) $(WORKDIR_SETUP) $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_TAGS) $(OPTIONS) -a tags-match-prefix='norm:' -a tags-output-suffix='-norm-tags.json' $< $(DOCKER_QUOTE) $(WORKDIR_TEARDOWN) -# Build normative tags with bad adoc input +# Build normative tags with duplicate adoc input # Asciidoctor should exit with a non-zero status and then we just "touch" the output file so it exists and make is happy. -$(BUILT_NORM_TAGS_BAD): $(TAGS_TESTS_DIR)/$(BAD_TEST_ADOC_INPUT_FNAME) $(CONVERTERS_DIR)/$(TAGS_BACKEND) +$(BUILT_NORM_TAGS_DUPLICATE): $(TAGS_TESTS_DIR)/$(DUPLICATE_TEST_ADOC_INPUT_FNAME) $(CONVERTERS_DIR)/$(TAGS_BACKEND) $(WORKDIR_SETUP) - $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_TAGS) $(OPTIONS) -a tags-match-prefix='bad:' -a tags-output-suffix='-bad-tags.json' $< || touch build/bad-tags.json $(DOCKER_QUOTE) + $(DOCKER_CMD) $(DOCKER_QUOTE) $(ASCIIDOCTOR_TAGS) $(OPTIONS) -a tags-match-prefix='duplicate:' -a tags-output-suffix='-duplicate-tags.json' $< || touch $(BUILT_NORM_TAGS_DUPLICATE) $(DOCKER_QUOTE) $(WORKDIR_TEARDOWN) # Build normative rules with JSON output format -$(BUILT_NORM_RULES_JSON): $(BUILT_NORM_TAGS_GOOD) $(NORM_RULE_DEF_FILES) +$(BUILT_NORM_RULES_JSON): $(BUILT_NORM_TAGS_MAIN) $(NORM_RULE_DEF_FILES) $(WORKDIR_SETUP) - cp -f $(BUILT_NORM_TAGS_GOOD) $@.workdir + cp -f $(BUILT_NORM_TAGS_MAIN) $@.workdir mkdir -p $@.workdir/build - $(DOCKER_CMD) $(DOCKER_QUOTE) ruby $(TOOLS_DIR)/$(CREATE_NORM_RULE_TOOL) $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DEF_ARGS) $@ $(DOCKER_QUOTE) + $(DOCKER_CMD) $(DOCKER_QUOTE) ruby $(TOOLS_DIR)/$(CREATE_NORM_RULE_TOOL) -w $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DEF_ARGS) $@ $(DOCKER_QUOTE) $(WORKDIR_TEARDOWN) # Build normative rules with XLSX output format -$(BUILT_NORM_RULES_XLSX): $(BUILT_NORM_TAGS_GOOD) $(NORM_RULE_DEF_FILES) +$(BUILT_NORM_RULES_XLSX): $(BUILT_NORM_TAGS_MAIN) $(NORM_RULE_DEF_FILES) $(WORKDIR_SETUP) - cp -f $(BUILT_NORM_TAGS_GOOD) $@.workdir + cp -f $(BUILT_NORM_TAGS_MAIN) $@.workdir mkdir -p $@.workdir/build - $(DOCKER_CMD) $(DOCKER_QUOTE) ruby $(TOOLS_DIR)/$(CREATE_NORM_RULE_TOOL) -x $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DEF_ARGS) $@ $(DOCKER_QUOTE) + $(DOCKER_CMD) $(DOCKER_QUOTE) ruby $(TOOLS_DIR)/$(CREATE_NORM_RULE_TOOL) -w -x $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DEF_ARGS) $@ $(DOCKER_QUOTE) + $(WORKDIR_TEARDOWN) + +# Build normative rules that should create an error due to tags without norm rules referencing them +# Should exit with a non-zero status and then we just "touch" the output file so it exists and make is happy. +$(BUILT_NORM_RULES_TAGS_NO_RULES): $(BUILT_NORM_TAGS_MAIN) $(NORM_RULE_DEF_FILES) + $(WORKDIR_SETUP) + cp -f $(BUILT_NORM_TAGS_MAIN) $@.workdir + mkdir -p $@.workdir/build + $(DOCKER_CMD) $(DOCKER_QUOTE) ruby $(TOOLS_DIR)/$(CREATE_NORM_RULE_TOOL) $(NORM_TAG_FILE_ARGS) $(NORM_RULE_DEF_ARGS) $(BUILD_DIR)/bogus || touch $(BUILT_NORM_RULES_TAGS_NO_RULES) $(DOCKER_QUOTE) $(WORKDIR_TEARDOWN) # Update docker image to latest diff --git a/tests/norm-rule/expected/test-norm-rules.json b/tests/norm-rule/expected/test-norm-rules.json index 522a6df..130668b 100644 --- a/tests/norm-rule/expected/test-norm-rules.json +++ b/tests/norm-rule/expected/test-norm-rules.json @@ -55,6 +55,18 @@ } ] }, + { + "name": "formulae", + "def_filename": "tests/norm-rule/test.yaml", + "chapter_name": "my-chapter_name", + "tags": [ + { + "name": "norm:formulae", + "text": "This paragraph looks like a formulae to Excel because it has this < sign in it. Make sure this gets written as a string, not a formulae in the XLSX or else it will create an error in Excel.", + "tag_filename": "/build/test-norm-tags.json" + } + ] + }, { "name": "rule_with_newlines", "def_filename": "tests/norm-rule/test.yaml", diff --git a/tests/norm-rule/expected/test-norm-rules.xlsx b/tests/norm-rule/expected/test-norm-rules.xlsx index 85b4bdebe36d174c50fa3856a0e0b08fc028cae5..0309eae2542b4c5138de46583c5a69e7ea4a3bfe 100644 GIT binary patch delta 2685 zcmZ8jc{~)_7oV|A)|ruQ44SMpV`)5$Eqi1)B0tL{vczCyAH>+7OoSmJV<@5QH1?1h zN%1U2Mn;wr*;+(T^+UhU=ly#3pR?S1&$;K^d%pK%Y2<2>u$Jr`LI41O3ve^h!_`cM zY$gu`0PNTR0D(QNSCA(*BOKE zHY)F~u*RTU4}MpM8Tf=bkqkAM8=sH%=`KFkhLdoh>?VF1UE;}BJk9M(NFMLtiLK6m zFJp1po#ax_@U6riI-;~}KA^P7=q*we!DY=-xJIcVuBEYD*Drk7IU@AQIc(`TA;Vtr z(dcTu_ioWDKr~9PpNCCQ5q+8CPK0b35V@V!tY7;cnCR(ikN`eHxjIYMh`0YiFs{RC zgyX1D-k0*!Fo zeB{bKS4I9-+~SdKk4TdR(JERmE{1;FZFDPZe?oS)Fe{{}7mP_)H2wKJc)|K7XJx9? zPkAb^V!EY-M%@Mep4R-DBBQvyw8Gf|0Oz~7_1EPzJCiJR0vpOB+qDyf?)iX}SH%@6Uk%Q^q z>Ko#IOp-E{WM!*V&omYis`VY5G?=z4yz|3zW>u#wXd>b(#~1y)nbNwW>1mugBQ8=} z^TOFA{2+v`8EnyrsYC@%1RHfon*@gQDEtuMzy8j|Lhw3O!DY}Uc`V1w`@961Qcqv0 z#yU|Tb80N77UKPWs&~-DY7I&Fv$Uzd?7�%c#Ssl`eo+y+BuGYdRjXoHLd@W%}Vk z_?IVkrlBFqiy9F-M&v#_R5p#<+!;A_-hm_>eh-&Du?9AgzlIl9s$WkgxR)M7Ej-9l zDx{`(y;!G?DTKobb#K7%+NQMnrq5;Wn7>xoyQI)RoM@~=-;8NL8+vFEzL~Lb5rV|* zEa@;fCU4`MoYOV|`gog#iuekeYRQ9|)BT5((^>+8rL9Ni&Q|is2P)6py=PH{B+>F~ zT5!x08Agzq3`15yVh49xh5H}C*GQs1unXB*68{4*g(6D{i&{OFG{O6<7p83q@bNw0 z9P;v|3sOp>x)C}X_d6L*fQrQgzbI9|sMK<-<)GIo7Z-V%)YToDE{Q=6GV>RvtBN@Z znge)J`9ZW^cZRz=-ajbz5SG+DK?US0q=+Yi`^5e%t&;Qw1JfNjxeczk|0%G9E)0eh zOf|fP(tK00ZU{{zNHS=BM21HIe&xKr!H7O7ey$gsPwQK}+E-pxQ;g7wFB3Lm!x~LW zMa=rlJ|hNrszt3TzA}`kfgMh3>b&sDV)$VwrXk8oyoPrcCdoGoBV`06!ixhE-LwSI z(}Np0)joq`qY%!tTO~ZucTXGQ-^?VxD-^`&kSj{~p#AmSm%@s+d}p+>*}q$CmsWD3 z{Av@&H+-aKGOAWx8tpsqcaZWgIKI$z?m8EL^r;{es>-u4_{K9bq2>tge75orxEA)w zCDhzKBmSXXsg<|&qLJ-Wd?X2a$q%;Q%CBkVa5Rv#UoO>|f@@NH<>Jc?0PKSvG2ld~ zuSbZtmwi}>AK_x?KEmZWx(1D*h2qxhGv&aD5@aKo}bdu z)+92AVEMpDsC+s?VpO_qp*!@X5`Pdl$#8hXa2VVe1*-_a+g+0#te>DKxiQ-;H1ZQI zhqaSchTQLjU4Y}@)T0iEW)_@DjL)6i`t0WM9o`Nb{u*F}l12YW?fju@8H9%$-{03> ze5zLDi?Qw#Yw>$xG-r^e)g=d8#<@Ga7(P9|{S=VIVO_m5K3Z7ANReZna!%`cqgumw z(Wu?JjA|i+5(YHSPJMW(>zePX-eEMEhf*BtGie|0p_e@D3r{+(G~uQ|VnSOsN0flK z{%A%bYwi~<1E<}(T$Q&^X1P9CK2;g9X592;IVt3rl<2ehcbG+xqlw}1FYdlE2riIf zXb(!0bk(j$m!YU}+mjcm>VEE{<#p?8DY~G(V>w*%7kQP%&Z65GfA}Q6?6C^9WCOj; z^{$p5DmrRzE3RPIZY{8;M`BF_1EJ|54Pv5f7e;HtKLhaAHt9;(7lG4_mA0vZKc2kz zkPUY9ZCmCL%IMNe*Iv)GPQX7?=a&#=CGN%FAZ;!z5c74oaR38CRCs@7)9H8_*Uh5Q zO{$hc`X)e;Jfaw$YC}7rHNx@n@)N?6A~SHc>|r5Gtns_`IjIoRAjU>gVv6Q;o~ee@yfN079Rv}pff+snsvU#Kq7Bcv%~%f=nY71BsGvH3k@LdboEi}ncN;$i zuA%obv|II9Z#C&)V&SeuQz;B8ZXe~z5s9JdUOr37mn+DbF2E#c3*A|%Ev9kXk}t1n z%!k<|33q8l?8JJ6sdpZ6qq3;y*T3OBf0lP=e&sjC--w(DH?}3$`3}lOpPp^rRgXU* zTr%npSO1c!D)A|2QkT$b*OvKR>&unFM>1CJr1F|s%y%R|{3qbI3Uh6}7bi;L7nLTR zw|$5fdd%7pvSyXD=N_Y2D3vRPmD+_qukl|N9 z8#4i^MNhS5kP@#=w;2hFvHS+6cRdP0umc2JIPc>KmM%^tx&Ag`?E^BTvWl5+- z$SprTc&O?1+gm{q9d}nT9JWLZMd=mJk8Q%!gbwMbZ&zP(_HezOYfH3UKjb{#ctua8 z7m);(K=ig?nlD{xU$eW0MLGyY>-Epz++RJV*K(DY6tw9MokS`Q11U1~k8E1|k}@=F z=F!b%#i??RTVaC5+id0d=ds(IrSEZCwto*yMpftzlFm%?YQ2bG*UlKFZrf2#KJdjo3Hvj4muEMo& z`w-}wd_n@d*NUL`Iy}f81n!SL5pX-9?(hL1Mh1oWUkD2F-^ap#pXuND`OjuWij=s_ g(R~N|PeFUnV#=O_{b>GKLlUKUiOYjlVEd~70;e9RNdN!< delta 2488 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 diff --git a/tests/norm-rule/expected/test-norm-tags.json b/tests/norm-rule/expected/test-norm-tags.json index 101eb8b..f5d974b 100644 --- a/tests/norm-rule/expected/test-norm-tags.json +++ b/tests/norm-rule/expected/test-norm-tags.json @@ -6,6 +6,7 @@ "norm:paragraph:inline-anchors:entire": "Paragraph with inline anchor and something.", "norm:paragraph:tag_with_newlines": "Here’s the first line. Here’s the second line.", "norm:def": "This paragraph has two tags but we only ever get a tag for norm:def.", + "norm:formulae": "This paragraph looks like a formulae to Excel because it has this < sign in it. Make sure this gets written as a string, not a formulae in the XLSX or else it will create an error in Excel.", "norm:table:no-anchors-in-cells:entire-table": "Header 1|Header 2\n===\nCell in column 1, row 1|Cell in column 2, row 1\nCell in column 1, row 2|Cell in column 2, row 2\n===", "norm:table:anchors-in-cells:cell": "cell with anchor", "norm:table:anchors-in-cells:entire-table": "===\ncell with anchor\ncell without anchor\n===", @@ -55,7 +56,8 @@ "norm:paragraph:inline-anchors:inline-anchor", "norm:paragraph:inline-anchors:entire", "norm:paragraph:tag_with_newlines", - "norm:def" + "norm:def", + "norm:formulae" ] }, { diff --git a/tests/norm-rule/test.adoc b/tests/norm-rule/test.adoc index a8ca907..59abc0d 100644 --- a/tests/norm-rule/test.adoc +++ b/tests/norm-rule/test.adoc @@ -51,6 +51,10 @@ This paragraph has two tags but we only ever get a tag for norm:def. [[def]] This paragraph has two tags but we'll never see either since the 1st isn't picked up by the tags backend as a tag and the second doesn't start with norm: +[[norm:formulae]] +This paragraph looks like a formulae to Excel because it has this < sign in it. +Make sure this gets written as a string, not a formulae in the XLSX or else it will create an error in Excel. + === Chapter 2 - Table Tagging // FAILS - Tag includes entire table but has adoc === prefixes/suffixes. diff --git a/tests/norm-rule/test.yaml b/tests/norm-rule/test.yaml index 9c92f70..01aaf76 100644 --- a/tests/norm-rule/test.yaml +++ b/tests/norm-rule/test.yaml @@ -21,6 +21,8 @@ normative_rule_definitions: tags: ["norm:paragraph:inline-anchors:entire"] - name: inline-anchors-in-paragraph-inline-anchor tags: ["norm:paragraph:inline-anchors:inline-anchor"] + - name: formulae + tags: ["norm:formulae"] - name: rule_with_newlines tags: ["norm:paragraph:tag_with_newlines"] - name: table1 diff --git a/tests/tags/duplicate.adoc b/tests/tags/duplicate.adoc index ad9d3ff..ce21a30 100644 --- a/tests/tags/duplicate.adoc +++ b/tests/tags/duplicate.adoc @@ -2,6 +2,6 @@ == Chapter 1 -Before inline [#bad:duplicate]#inside inline# outside inline. +Before inline [#duplicate:bad]#inside inline# outside inline. -Same tag [#bad:duplicate]#duplicated inside# duplicated outside. +Same tag [#duplicate:bad]#duplicated inside# duplicated outside. diff --git a/tools/create_normative_rules.rb b/tools/create_normative_rules.rb index fe0de78..18aeb0c 100644 --- a/tools/create_normative_rules.rb +++ b/tools/create_normative_rules.rb @@ -243,10 +243,14 @@ def check_allowed_types(kind, nr_name, name) end def fatal(msg) - puts "#{PN}: ERROR: #{msg}" + error(msg) exit(1) end +def error(msg) + puts "#{PN}: ERROR: #{msg}" +end + def info(msg) puts "#{PN}: #{msg}" end @@ -256,6 +260,7 @@ def usage(exit_status = 1) puts " -h Display this usage message" puts " -j Set output format to JSON (default)" puts " -x Set output format to XLSX" + puts " -w Warning instead of error if tags found without rules (Only use for debugging!)" puts " -d filename Normative rule definition filename (YAML format)" puts " -t filename Normative tag filename (JSON format)" puts @@ -276,6 +281,7 @@ def parse_argv tag_fnames=[] output_fname=nil output_format="json" + warn_if_tags_no_rules = 0 i = 0 while i < ARGV.count @@ -287,6 +293,8 @@ def parse_argv output_format = "json" when "-x" output_format = "xlsx" + when "-w" + warn_if_tags_no_rules = 1 when "-d" if (ARGV.count-i) < 1 info("Missing argument for -d option") @@ -331,7 +339,7 @@ def parse_argv usage end - return [def_fnames, tag_fnames, output_fname, output_format] + return [def_fnames, tag_fnames, output_fname, output_format, warn_if_tags_no_rules] end # Load the contents of all normative rule tag files in JSON format. @@ -492,7 +500,7 @@ def create_normative_rules_hash(defs, tags) # Fatal error if any normative rule references a non-existant tag # Warning if there are tags that no rule references. -def validate_defs_and_tags(defs, tags) +def validate_defs_and_tags(defs, tags, warn_if_tags_no_rules) fatal("Need NormativeRuleDefs for defs but passed a #{defs.class}") unless defs.is_a?(NormativeRuleDefs) fatal("Need NormativeTags for tags but was passed a #{tags.class}") unless tags.is_a?(NormativeTags) @@ -511,7 +519,7 @@ def validate_defs_and_tags(defs, tags) if tag.nil? missing_tag_cnt = missing_tag_cnt + 1 - info("Normative rule #{d.name} defined in file #{d.def_filename} references non-existent tag #{tag_ref_name}") + error("Normative rule #{d.name} defined in file #{d.def_filename} references non-existent tag #{tag_ref_name}") else referenced_tags[tag.name] = 1 # Any non-nil value end @@ -522,13 +530,30 @@ def validate_defs_and_tags(defs, tags) # Look for any unreferenced tags. tags.get_tags.each do |tag| if referenced_tags[tag.name].nil? - info("Tag #{tag.name} not referenced by any normative rule. Did you forget to define a normative rule?") + msg = "Tag #{tag.name} not referenced by any normative rule. Did you forget to define a normative rule?" + if warn_if_tags_no_rules == 1 + info(msg) + else + error(msg) + end unref_cnt = unref_cnt + 1 end end - fatal("#{missing_tag_cnt} reference#{missing_tag_cnt == 1 ? "" : "s"} to non-existing tags") if missing_tag_cnt > 0 - info("#{unref_cnt} tag#{unref_cnt == 1 ? "" : "s"} have no normative rules referencing them") if unref_cnt > 0 + if missing_tag_cnt > 0 + error("#{missing_tag_cnt} reference#{missing_tag_cnt == 1 ? "" : "s"} to non-existing tags") + end + + if unref_cnt > 0 + msg = "#{unref_cnt} tag#{unref_cnt == 1 ? "" : "s"} have no normative rules referencing them" + if warn_if_tags_no_rules == 1 + info(msg) + else + error(msg) + end + end + + fatal("Exiting due to errors") if ((missing_tag_cnt > 0) || ((unref_cnt > 0) && (warn_if_tags_no_rules == 0))) end # Store normative rules in JSON output file @@ -568,7 +593,7 @@ def output_xlsx(filename, defs, tags) info("Storing #{defs.norm_rule_defs.count} normative rules into file #{filename}") # Create a new Excel workbook - info("Creating Excel workboook #{filename}") + info("Creating Excel workbook #{filename}") workbook = WriteXLSX.new(filename) # Add a worksheet @@ -593,8 +618,8 @@ def output_xlsx(filename, defs, tags) # Add normative rules in rows. One row for each tag if multiple tags. row_num = 1 defs.norm_rule_defs.each do |d| - worksheet.write(row_num, 0, d.chapter_name) - worksheet.write(row_num, 1, d.name, wrap_format) + worksheet.write_string(row_num, 0, d.chapter_name) + worksheet.write_string(row_num, 1, d.name, wrap_format) rule_defs = [] rule_def_sources = [] @@ -619,10 +644,10 @@ def output_xlsx(filename, defs, tags) end rule_def_sources.append('[' + tag_sources.join(', ') + ']') unless tag_sources.empty? - worksheet.write(row_num, 2, rule_defs.join("\n"), wrap_format) unless rule_defs.empty? - worksheet.write(row_num, 3, rule_def_sources.join(", "), wrap_format) unless rule_def_sources.empty? - worksheet.write(row_num, 4, d.kind) unless d.kind.nil? - worksheet.write(row_num, 5, d.instances.join(', ')) unless d.instances.empty? + worksheet.write_string(row_num, 2, rule_defs.join("\n"), wrap_format) unless rule_defs.empty? + worksheet.write_string(row_num, 3, rule_def_sources.join(", "), wrap_format) unless rule_def_sources.empty? + worksheet.write_string(row_num, 4, d.kind) unless d.kind.nil? + worksheet.write_string(row_num, 5, d.instances.join(', ')) unless d.instances.empty? row_num += 1 end @@ -647,7 +672,7 @@ def output_xlsx(filename, defs, tags) info("Passed command-line: #{ARGV.join(' ')}") -def_fnames, tag_fnames, output_fname, output_format = parse_argv() +def_fnames, tag_fnames, output_fname, output_format, warn_if_tags_no_rules = parse_argv() info("Normative rule definition filenames = #{def_fnames}") info("Normative tag filenames = #{tag_fnames}") @@ -656,7 +681,7 @@ def output_xlsx(filename, defs, tags) defs = load_definitions(def_fnames) tags = load_tags(tag_fnames) -validate_defs_and_tags(defs, tags) +validate_defs_and_tags(defs, tags, warn_if_tags_no_rules) case output_format when "json"