From 91ab02439f2c072ce55c89b04c15c8a5e8390bfa Mon Sep 17 00:00:00 2001 From: James Ball Date: Thu, 27 Nov 2025 08:04:33 -0800 Subject: [PATCH] Fix for having two or more links in normative text Signed-off-by: James Ball --- tests/norm-rule/expected/test-norm-rules.adoc | 6 ++++ tests/norm-rule/expected/test-norm-rules.html | 10 +++++++ tests/norm-rule/expected/test-norm-rules.json | 26 ++++++++++++++++++ tests/norm-rule/expected/test-norm-rules.xlsx | Bin 8714 -> 8794 bytes tests/norm-rule/expected/test-norm-tags.json | 6 +++- tests/norm-rule/test.adoc | 4 +++ tests/norm-rule/test.yaml | 4 +++ tools/create_normative_rules.rb | 22 +++++++++++---- 8 files changed, 71 insertions(+), 7 deletions(-) diff --git a/tests/norm-rule/expected/test-norm-rules.adoc b/tests/norm-rule/expected/test-norm-rules.adoc index 437b65f..5d1fca4 100644 --- a/tests/norm-rule/expected/test-norm-rules.adoc +++ b/tests/norm-rule/expected/test-norm-rules.adoc @@ -81,6 +81,12 @@ It's got 2 lines. .1+| hyperlink4 | DEF <<non-norm-anchor,custom text>> GHI a| link:test.html#norm:hyperlink4[norm:hyperlink4] +.1+| hyperlink5 +| GHI <<norm:superscript>> and <<norm:subscript>> JKL a| link:test.html#norm:hyperlink5[norm:hyperlink5] + +.1+| hyperlink6 +| JKL <<norm:superscript,hello>> and <<norm:subscript,goodbye>> MNO a| link:test.html#norm:hyperlink6[norm:hyperlink6] + .1+| table1 | === WITH anchor diff --git a/tests/norm-rule/expected/test-norm-rules.html b/tests/norm-rule/expected/test-norm-rules.html index bb3703c..c196db4 100644 --- a/tests/norm-rule/expected/test-norm-rules.html +++ b/tests/norm-rule/expected/test-norm-rules.html @@ -243,6 +243,16 @@

my-chapter_name

DEF custom text GHI norm:hyperlink4 + + hyperlink5 + GHI norm:superscript and norm:subscript JKL + norm:hyperlink5 + + + hyperlink6 + JKL hello and goodbye MNO + norm:hyperlink6 + table1 ===
WITH anchor
WITHOUT anchor
=== diff --git a/tests/norm-rule/expected/test-norm-rules.json b/tests/norm-rule/expected/test-norm-rules.json index c9992bc..8f51d59 100644 --- a/tests/norm-rule/expected/test-norm-rules.json +++ b/tests/norm-rule/expected/test-norm-rules.json @@ -300,6 +300,32 @@ } ] }, + { + "name": "hyperlink5", + "def_filename": "tests/norm-rule/test.yaml", + "chapter_name": "my-chapter_name", + "tags": [ + { + "name": "norm:hyperlink5", + "text": "GHI <<norm:superscript>> and <<norm:subscript>> JKL", + "tag_filename": "/build/test-norm-tags.json", + "stds_doc_url": "test.html" + } + ] + }, + { + "name": "hyperlink6", + "def_filename": "tests/norm-rule/test.yaml", + "chapter_name": "my-chapter_name", + "tags": [ + { + "name": "norm:hyperlink6", + "text": "JKL <<norm:superscript,hello>> and <<norm:subscript,goodbye>> MNO", + "tag_filename": "/build/test-norm-tags.json", + "stds_doc_url": "test.html" + } + ] + }, { "name": "table1", "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 475bcbdea9f8d769d0bbb240659213edb2706de6..eb78facabc7eec85f0f5c522c88b24a0507ab566 100644 GIT binary patch delta 4147 zcmZ8kcQ_kf+YXJQf*4V1M2J13s1a1GwDw*_ja03wt(0iZ+G3VcD^^i^RP9--R;?68 z&DyK2(Z1F1{l542e&?U(y6@*c&vnjuuIrq0M=H-M)9R>S0n!5i05SkikiYq-KKPde zT0v}0O%;y47E;Jz$Zx3Yn$jHf>4#b!A-?`C9eYq$aqsb9plp-7^uinNpCoJeQ3!`= zEbYi=vf_Hksfo~-TGEfUn)@-MIyqFx^r=Lgd4EjsEqlQR_I4hce7Ti6R1;XRd-{-- zceQ$bME5gep-BXuU^DRJ7J*p!;At2H$c;6*-#}X64bSD&+oN&7-n$6^_KpM*vm&{f z+U;Edh37+Iij9x?nPez#mGQWF?l!Z;xDXy}dsg(E1K*~;-R&$Xp13HM%6>=x%AHh@ z(Kz)-RYbT`8ufthQVei^Lgk`|;Fh2SjeuXx4sYOD@i;xNGRuC~7j>2tU*l_%z{E8~ z&gElu(f8)pO&!+o^9)~N7I!P`bH4-9e;!x0HBku>F;7r6#1zPT{AR|$2EYQT#fbtv=vI-eru`*V=<&8@uIWM zFvHK>=;PtuM}p&-VfjJJZ>vsCKIIgr#D=oe-z|LnB67W} zeR{FEnG-z5$3ji-q!}z)XOL>!#cti+Tb@W|nb`4llO#jm^1YGwg{sYjWaj#kTOw-4 zUTYjNvh)_v*16O|$$Nu!m<7pbo`;_wu?6Z;JIPY!bvvI=VUu@in}4!+c8~Awe38r~ zoXE0+!V=^@9Z%)#d;B&;dd8S69H(un(>Y`3%6+9hTR**RZ8&(caIAvM87PpiSzh>J zVr08wyMJ*G?RTl)Rlv|;mJN8U_rA_PvhcS3wu;~0Twb`os<&}Z$;xrviIP=Y45F=> z62Urz&ujD^T$mcQl$mu>J8OykfVVx6{Op^1sLb`-zHI}4_tdESm+{*A`{mx?8vb`! z8-&y5R5sJbi2=yNP%i%hIRml^+-%(zpgde9piFN@wNP>imnkgN&z?=L1UR`bynE-W zxoZyHHLpIKJPvRQbcs2wyhob97<8mLl?Jk3N9;t@FWI4Ajo6vIVwc_Cmn53Od?VBW zsR!DunXFC1R5<+oKaf}T8o%1x@}j^lo5Hd%_(C`v4?SNMaYP3Z9iu1>G532(=}q;Z z_|6vMh;DNIG*Jj`!5?Za1puqQPZAH}8NA=2flk|>mA*p;7Nap@8AWKNb%r#?i>}pf z%us{PA`*Fgh1OlqZL%j7x&UNt|sSYP6Z$pc7?l=H0r^MXu^5%UHtLrSpNkCyyyq zE)PD+D@?9rc!g2jBA7AGnZ7Ot=b6{QCwNS0Q}h_TjEL>%*Ts3zPmx^2)GLE(scew5 zy7lvwt_ZGu-W`zoP%tC5gslzE_PvOuH)$)cL5j8n+NJZGy@!)sq8q_Q!uKdHhXE*tOmy!Td%!Jx5rV4h5{o7FOn_v0oQK;Kcu* ztK8Jx=W2Z8{hhYpCDqgQPoN^n`$)E^W{tu-k6vFst zO}>J56`|2~u+HrS{r@e*qsO`yQ=0chM7exs)35t{m9g&2 z)jzuh)x{?W+O?H1*MjdGXh;BIap9no_ynX~+dESY6(G!!gY1ccT}5PcKF5{Gk2aee zWV%d>eYTvzE_QHcriuv$eO97~*Xl*_yJH~%c5o=u4vk7`U@BnAo{s-(27Vf?Du!F+ z)^$!`#44UYMI|G5YE14L;czQrx{>{Kid#>gCnJsZqMGfvL`-++RHjN(!MSQsRLk0R z6HOz%L=x)Q_1R-u#dNj+vL~y>-QHEWOu_odT&HPuvdX+T_K%+?Y!prRi@|%>ECwu5 z5nL+qB7Blb$so+=Axu)6rfZe&`O`ys=Ki~3*s3;x^dWt~Xze~EOZH!f8yyl|DD) zI=xnR^;zx1tbr0rsz+1bBY7@#U54K#M!#-46%V{IpIOvYF8^zKw#nvOx`OqaR?F?p zcW0F}LJutVJs(>|7B~fKUg&vsMm%bvOb>ULrOxAwEC~7z!2h3 z^!IM3zZu$FdKCcJXHJ}FV8Ob05F|mr%B`Mx?9`nMzwK8ahii$54B=`uo5Z)>H)`e0 zaxoTMV|2wb^HqTh)H6_m2oriH#W~V_DG*H$X5Rw?Z^ujfx?NY>i{a+@T5A4HoFI`s zxE$E`{Lyyjv8iqSRTS-NV#LkaGR>l*W+_jqkoX||m+O;Zda);FLfA!02My)KI9{dU zARa^lnp;sln)dEfM7}|f?tn|Zj~Rm8loFXGHdEHddA>5LzMZ+p9I8A64R`O;C+D5% zfa;P|J-wjB=OW-X4-cAokBb4sk(A8r+-|SchA{1+wQHvuBGG8n^N{GUmtco4JF25V zzSoiyem5{@o?3LL)u?AC@8K+WJZ;At&%n&-=D#f1^mh&~ovx(9p#g#zP>S!_6FkeOHR)wHBCJ!R=5 zvHYpbYhRA4zMYeXxsYG^>Hxys{!69k+dMbQq ziJv^QaVMOOSZWRsqYUFqOPNt{}toq<=Kq?T6?6;0QswNVJ;o`TCZ{gE`G#!0!VEXCyK^1uFK|elK@gEDndh z@A>1GS~R!CIrUb@^N;qV<)3K}NuM3|905@ZE^Q)f*FPou$iFQ)FmqYMI0!FYG14Wu zk6AaE!45YCv8nQ$vV5ot{Wfi=@c8s#aFsx7QJ}I#Rza78FO=UL79#O%?I=@`@aB|1 z?nqN^c7@-ibSgsD*HtzV=I6t$teP#YA1mVL4&vt%?tXh%eE(wD%V*>~W1wDOklAk= zT+u2POCk>VeQ_xA{%qSZ6edBKV5JjTl%tjn#$u=>gZ7MX{|?h?a?#DymV{9AaI)rE z$xiNdD%qY`2-Er@(+>8{Y4D9X*TCfxVgk1(nhnrw!Chfv0K2%apC6L2=Vc}Phe{;% zZxpx0>PrfUI?E06Q7{Hh@R&n<>&nP4($Kn^nHaqVv2IJayECN0rxc&f-w-Aq`Qyeq z_8ZY!AQlxhQ%8wed?YEuGhn7f3cdB3O%+R$es+@8%=(D8WbQV5c9yD1^!U z#Prj0Z|AhUYeDh$g5 zABOCp=(s>+1;*kw?QB>z8<-XyZEkW(N>nD(n5Rz%NoXJNX^xwGuM4hOaT z9gDWbGwSLD4$&IZ`Oj$d#_)x_Vf%LiIHQE&F^hepua~!M-y;XLH;Qqp^w%1(^cdLi ztKDZy#zCTE=!|W<$+<0Cr-Ibmr7zk>vS23T1*aD7RUZqP_A`Z!NK2Dh2!{@;ItzZv zQ_fy-avt#|on^O1l#wAsm3{RL%Y&*+o&2@f$G3CM(TY*yc-HyJi*PX(v z@1>AJTnFUUZ%KJzK3fWDtJ@2x7{-Yjx_XDXQp7!qaS)Pmj|}duCN^Y277H7PPPI$; zs5^)@9XvNPk7q1^x=!iklte8%HqB^FEg}xME*jGxhLG&r4uewPQ=5XZqaCtf2IfdU zO?ZKv6Mv9DN`N0}z^}qBF4s9-dyZJ{<3oa=*U8P6qOO`uUZ-99NKaOMej{7{;!*kD#H?f=+(pziVRg1QM`ESX9jBlLF6*FM6O+BR`@4eB1oZ6Zag`W59;uT(mnx=|fu& z1=0gksg!d=Vi*T$m&}QOT-o&QO+Ugo>?;3i_UYu)kB0i6z9J-g$XdN;9-40>U2z^% z>x{Tr@p2$}uKOI5VR_GkL1*@!qdjbulE`~I$zfrx89AQ)hD9|<tM7js2KIcAObwLr={>MfV z5sP2>Z{MAG%y#S2B??24m%$nO7vZ4_muMBL`Zve^7rC-aU!oFr?f>s5Nnui#8ATWi xk$s{ij179}H~;e|x$NKnj6dxJS+Xw^BKyu{>@h=R-?Kzg_I*u>N{qE4dl;JR zTa;{N>rLPLec${3pL3pb&+p#fz0W=OIp;ploz{rg02}I3QL_O6fOCK}T&R`iCr2NrE}NrX8oXR`7jeIS3V=&>Rr-33m35#cn6ZDSb6EWW*$hadvb?S zc)4kH$jF+f%rdsbqrvGoubGg5D!5G(0mMT%KU0|~frnW{e#Smit>pnkI;^TiFhMgC zzck4cOirDNPplO(8IV12~W6*yHi(y~Y#F2ERQPlBH%AQ0p=QA54uLO0Qm%%?%JctJgflb-1zb3ZwHzMDtjSmvTKIKCT%V)pN z;u~C%d;Ml7eYM`n*FLp-JuciIYq3|laRtiH*XxE8dv_6K5#;*WxajldyCkdeyp^J= zR=>0!zWCY{^45D39&u+< z6BwM~ex~xo-izDc{eByv^pYlL_Hx#BS@E8;wLvO4+l_2nn_thq9rE`}I+?(xw_SY2 zsv3SY{KTFzEdR$=$a8^HR_$VNV{xHBGFE{mR`5y9;Z8B zSJ1N}@7E5t4m$HjGhA8tFe4g+=l1(D9)A{7Svpe18%=4o6K{E+J5{oXM6+ zPhmKSE#zAljGAoFN?qZ1$A%8-=rmdj#s^epg9_{pGi&q(;f8|n{u4891k(;X$9y42#uwk# zT0>=Nbr=IlUR-zvSG1!pgNT;CZ86YDxYWps$wUXO_{3BYOZtX;P6FP3MG?{0f}SkP zW9(Bnx=@6?_I_D&!PmBt80MdonAbsIVAl_QB!FwLVLBk)%&g){;d*g1<%xloB-l+@ zxkr#*#FXcjvs82-COsARiV4QU8~km#G|3>LXZMCttvbHByybR;-lw_MpN>YvYX)hq z4SUUTOh-D1@t+q;Y57eESzgC!{sL9KDzQzeI`Ajs^|W^$&BV7fyDG@< zKU7sZub!SREJ(cSt&ywHhDB+L6zeNLb{&Da5Kf<(NqhP1iATp-f&SV%TOqJ`TklHr`a44I{FGakk@2nTx;o`|@H9?<_}X$a!jT2v3n*%&sXG^viqY}Qi@gXedLUw* zqlOE)o@xK#Q-p(YW@>#Kw_!{8uPtuhNY_XAk}P@E3BYPx5TR7$;_yWM9sQZE3Ogi1IHW^hKEq7Fd5y=2oiKup>b|Zj9lI z?d9a)vXk|ITgZJ+tK8fuLR+~|y{!Lwy^9%Mjk$@{A=!TXt^U?JOd%|MIo>N;f`>(v zvRcD+sUqc#i#E$_70_cUiASKALRWj{NN4^7T75<4S#y5=-~{yeaDEB=Rx#Uqk>d4* z=G9nJboFQ<7=A-xZR2T@Y+& zX?Qbg<{^rz2I08rGHx`dzuBlTZUKC!$rv*bL*tZ8OzCkPT`oEYy8@HTr<~^B(Z6U(jfo#LR79PBB&2!gG1IxD5)f(LI z0={SY7Z974PBprMPlK}2#=-dO>ffkXrLxKodRu;nOjqXR`6qo@iS&s|vc^wJb~=lD za^Du^c%E3FPfyYeN~c%S49cZ9@OyNFVr={7rB59NS^|i>GhGZ7<*YKY#N*H0FxAWGWzyiMKzl@w$dF0zJ66CcTrlR$vy2FVyU>(PkYy>WI%d z4D6ng-gI6HR2hP)RVgTx&Q{}#-vDD@_O0iQJ&YN-GD96Uila^0wNdl90i(Lbxd;+X zQX$^l8D5HEBwMpUKOVdUqV2*I{PRMWbztddYeZS%k8g|zQaV+w`5`L>?R zw||@^cE)k2bl-1L?+V(E6U~bEc*?dF?g?yxsAcYCqS~?sbbw!V$aMIlYHgDfcgODM zyI)7e_6sl6%><#Qp1ey!?vc#a!rZ&3Mxb9?>lY_71t7Zz3s(Zl4+pS{-YTOT-<9{- z*$cN^OK5kXDZ-7l%)zu=D*{nW!Dr^@f^=pI@WXRo>BJNPKb^&5u=@4tIm4Sc-g|5E(XUEI9H9m8+EwhyUsc^M5{6p;nZY z0p!wx#?@u^!Ny`|O2oC~}KLVl2~>QrX`P z^fnmWwEtDh9!j-Q+>v9@gK!}{>=)c}IBnFGs8#e6kmPs=?|Mbio89kvb>56(#~CLj z5my-uYN@8aG&5;RI4zYlr~jeV#%%3$b+MKjUK5FTL()E zwZ?_P+_8}O9P*9jHL>|b2H?`=<@!ql9dyjWjUc&)rWYxd?Cvdc1~{443^#lj)0Rs4 zsRpCPWEQ%wJOhR^tiE+)_I4+C+Kw#|TB))zm^6t)Uev~%i|7IPp~$J9^nQd|&$r#Cjf?D(q7`j4kSb_#kFW*R2#G716T`z(=AYe|=d;IZqwo6q z+LYAb1m28&SJIX~1Q_a4P|8yM_gtKD4JLm!#f8IAXX4fWpgoxC8M+MD{A+{%MeT6K zGjs?y_~*Q5flxTJq#<}Iu4mLDpzyPK@c+LR0KnOqXN%&`E{^Ddq;o(-|C!C-TmD0c SqWmWxn{kOBNjnEUi|{Y> DEF# outside. Before hyperlink [#norm:hyperlink4]#DEF <> GHI# outside. +Before hyperlink [#norm:hyperlink5]#GHI <> and <> JKL# outside. + +Before hyperlink [#norm:hyperlink6]#JKL <> and <> MNO# outside. + [[non-norm-anchor]] Here's some text that isn't normative but the normatively tagged text has an existing link into it. diff --git a/tests/norm-rule/test.yaml b/tests/norm-rule/test.yaml index 8cc71d0..2db65df 100644 --- a/tests/norm-rule/test.yaml +++ b/tests/norm-rule/test.yaml @@ -64,6 +64,10 @@ normative_rule_definitions: tag: "norm:hyperlink3" - name: hyperlink4 tag: "norm:hyperlink4" + - name: hyperlink5 + tag: "norm:hyperlink5" + - name: hyperlink6 + tag: "norm:hyperlink6" # Table - name: table1 diff --git a/tools/create_normative_rules.rb b/tools/create_normative_rules.rb index 83bb13d..2e02014 100644 --- a/tools/create_normative_rules.rb +++ b/tools/create_normative_rules.rb @@ -1063,12 +1063,22 @@ def html_chapter_table(f, table_num, chapter_name, nr_defs, tags, tag_fname2url) # # Can assume that the link is to the same HTML standards document as the # tag text that it is found in because these kind of links only link within their document. - tag_text.gsub!(/#{LT_UNICODE_STR}#{LT_UNICODE_STR}([^,]+)#{GT_UNICODE_STR}#{GT_UNICODE_STR}/) do - tag2html_link($1, $1, html_fname) - end - - tag_text.gsub!(/#{LT_UNICODE_STR}#{LT_UNICODE_STR}([^,]+),(.+)#{GT_UNICODE_STR}#{GT_UNICODE_STR}/) do - tag2html_link($1, $2, html_fname) + # + # Note that I'm using the non-greedy regular expression (? after +) otherwise the regular expression + # will return multiple <> in the same text as one. + tag_text.gsub!(/#{LT_UNICODE_STR}#{LT_UNICODE_STR}(.+?)#{GT_UNICODE_STR}#{GT_UNICODE_STR}/) do + # Look to see if custom text has been provided. + split_texts = $1.split(",") + + if split_texts.length == 0 + fail("Hyperlink '$1' is empty") + elsif split_texts.length == 1 + tag2html_link(split_texts[0], split_texts[0], html_fname) + elsif split_texts.length == 2 + tag2html_link(split_texts[0], split_texts[1], html_fname) + else + fail("Hyperlink '$1' contains too many commas") + end end tag_link = tag2html_link(tag_ref, tag_ref, html_fname)