V_*(A0DKAD4i*6y-1ep8
zY3x(XojJ?$20xRQ**R$nODh32X%33cd%P0KT|fgx*K7|1$6fuokFdB|l9@N&}ox
zKQSA;9t=ZFB*oo7sNV%(cd!x|sdla^Yv%#@p}s=%NoRrwKoYNp?YzeQ8t-cirFpXD
z>^xVc9%c`~2aU5eud4Z=Eb~gk6faNW1NE5)f|Z83-K)BF_WK@e$(?vjZvyNnM$vLJ)$l3eC#mL0KT|0N_zGD^YdW6fh9#{xaMfJ&O+;$ehx;7
zzeUycA^fWTSp9OvxB>Bi+6rs}E(V&rEQ&9qTF$Nb_+_A)7cO~>&_*kQW5B~;RQcME
zdTU->&l)w?RdSY$rg^l>HsD8K3Frq$sxrg1#fRYk>7&WQ^3|HQ(D++@#-Oi_8m9QV
zg!b3~l#ehYVv&3g#=*5<5V)m&P3wIh2U;iiNCeFXDYh4bL8wPs8}+WsD?l|aDL5wa
zxng5Kpm&ARwwLd8PhpFmIo}8tfDeH;fjxoVm(u;;I9MO74YYn%SQqHNUC-a12X+Hm
z8+jZ!9cZ56r{K?E(AK}mC#u6L1yf{Xi^JD?xAbG6pVwRQ^md>)I2ybJi1#yq);T(9
zAL)spHDX#1voX+|^|9bWARE*tEiE~IfPM3vIHgjO=mC7J>+Y3(;DR`K3-~117wEd*
z_h-o1pl3X50>#XS!8PD-pp0`A_hFa%#=iS4kzfNXz^~haUxOm9mExD~l{9Cmdz}qI
z>F=YlQGM6yU;>;3eh4()DZ*!I%6JT0js(^GmZMn2m%7Jz8F&b!X@jh36cc(6LVd)G
z!9c$=g#GfH?#t$a!@w1w46&m7;#0v2jwmv+YVe`1herU7^Rn{3SH1_){aLUBSP=}R
zzp0n*#Wa5TAh-wg@{3Qou0>x1)wn$)+wh&PeKqiJ;JU4(^A>O@7`Zm0&NIP*K=)rh
z{F}DDuA=-o87VTd+3?v4;7pL#&uP=bTtngpMyuihD42l~;U{DgAXby}$*RECe#?|&1d
z<$RiSdbYL)sN$jrXYi5wlfA(&KpNk=Orv&MyN8J*E5yt;QM~-uavQMzw296`P6k5_$BCd
z?MRYq{r0Y)D3hyl5`8AEfLI?A6H=J2KNd$%1LhYUeQ
zXb+7eUkL64E@B}`$Jfz6w9m4roBXJ?xLL>JcaV3}A)wSyR)MzJ0_c6lB!1^Tud&YC
zz_9vnE9$l|qyK(JzV(OFF+)-*@fK_VZUT8@At}GUYxb-maapq()Jf0B_3SRG-rdeC
zHmdcVO>dTahqluDzV(c4-HiuE_P^+!S#B?+w~o5#x}s-2rhYbCjmxUpO7X7K2yHcsc
zDj>_4O>^E`xwE9w)DI8PhU)^YTTjy`*rvGxy#xD>8@B7d>f{W*(OS_L_oF?lGTnQC
zw$!usyE5>gSG;H*^wsVyE=D7^ZwK_8yH`Eqa(&z45KxSfo=Z99@?FN_@LXJJ)zh9^
z0w3>^DDGA-ZN(D|!{+Hg^9*tBr`gwg8w0-{jhI*w>;T>aJ_$Yw=7XKUT43bX#n7%V
z1zJy)h6grj-jB`%CYJLw_P!~DA2gO5=y^MMul`~jd<#4UmbT$v9RC@78@vk4C}#`0
zw@MraS~HjR`EXLqJc!PLd3POK*8sMCsm9}T-M30{8sWNPV-s*YXpf6d$4f|e3wRMI
z&d@%VL>n&;T)ih6kC#*WSgq7WQ+Hh>P6KhoQ8;hhXDo;4#oECgSolNI%eH4!AuXd>p7x=oSk}GUYoJ4D5WR
z&1H-B-Wk}=-NZT5Y5!yBv@xU5w6YDH4?5YNbne%rAGrC4xMSh8?yL3yPk5_vNayw5LutPcgl(F`v$-Z{E_b&i9}dcS_&f*v5~PWN
zUTGGgN3k|2)z54vZLep?S=Zzx#mRA*4f2?gdaCcZ03_Mn>Ac2i9O=kGf!CZrW2RUx!<9ybl(QTCawLq`F^X`DG&U5b$C1vJODcJ
zJkPn$qO<=5_G|$h(0$ga!0_9}_CU{OTdSvj=ULXVl>MMh#o@2|jx#;PhT`f;u%(SX
zgPIoJtPXx-$)9dFzZ
zi9fQ4k3W!hSo)5C78Dy__x%=}ipN9yeqWy-P>1JO*5iYPIoeY}
z@Kk-rIl#reQ(7I5Q{K3zDwRqtd{Q6sZcARZ$Avk506nYrtAdoRcQuSHy|#J=RQmN}
zy?hBzHv>NBtde5piQj6u_Ra^6
zYgJBlaLaaHG%058L094Lpi!pHI^9M;Y;@i7aPvcbj19$y`jAojj(OH^rp04L?-p(E
znhV|ZiR<7mAZ|yu{Zc%u=~ky+GI+TfxDWWehf1USYuGR<&qFqcV>au-lQ?*Mul98*
z$L5y+jeU~riJw=x9bJ~+4_$Eb$P&bc;z#S>3%wrp!`~_s-st(kl__}^=Un^#jp!)s
znnGEpS=g-g#smF3i|}yOk}t-dU47QMEV|*@Y+y4_n#9LK-owMz4S~&C-Mz}<
z>nwJ_!{xz^pciM0mfws`1KlsDX%D!j`>X{ZiT7#GpOmJ&ylJrWH5Rt2Ut2A2nf=TU
z2X_IwUKh>(H08aapS~%oY&fK632Dc>N%3+$I=q`q8E1kd8`{rbQ-n>vDoso*2d*q>
zY$$$y4+i?%7HQfJ4(UDhy!TlDK!?}oAn4cF;}@Vk4w8-sdc76g+Y#t{hiR_m{Yvv;
z>`OzlflUM7bdU9Q3*II1aT}jbz&?E!(Pr%N5})??)D7p|{Ju|)CFzDs8vs2EPwE@eocH>i
z8r$AuVc)H!O{#9G&%-r+3-LP8&cm`E>-(h7FSS#18V8s3os%rTvlNe;t9)`2-Fn|7
zUS7BT1vy>Px9o6jZ=i1(mNgza*>wZung1A6toht1ghl`ef#
zgf3!2?{^#m%Ji(h-~HL#hn?u1XKCBOeU}DqX^pNp
zX2Z#{r9B?|eNdq9I^mz@PxJo%)XqLCf?a!B#E0gt=J>F~r%rfv?10CHVpZ>NZRFEW
z{n8Dmrh~k{8*+dT`?2c?khUNDBWVX}Z4jJV6Z{2~tv|?O&zGsk(9QS4DUE@@Yr(@#
ze0`Uv_^|n{hTEvaz_brs(zxTKA&Cvelim^8&Ib?rtrK3IkuyF{^icmESaeXfKu}9DL
z^}XLt@!08{mp;rzUE(_6j{1&Ic;=|#^4nFO`HRZd?@k%HkFB2L9A(NJhAkY_H>~rl
z!@A71AFyXdVDp=_A9Zbm4}EZFE_lQga;v4Mx9%&*s
zk!h{)#lT$eeQfnzxn~vWUteXxL4A8I&%1;^`j2(7$>uvcth(Yy$oPe8h&)skyU(U*8K4wGQx4AnDrN>%5QghrU_zl!Z-R-$Uuew_b91qThbf
zHPvv($5!j(Uk-Yiqx(GJXyC&Rqf=w`*Yz}}0
zw!xJ?IHJDetDde?BTFI(Vq~_$_GXecI#mUDpd+
z^lqa~d|cq#23Pvv$F{)t?*{&sGJ4)uwbzL}dM2_E_=pXov+H=M-KMe~!$ZZ#??Bpk
zXiw+--UeH2#~+uHr);j(J&gK}3qA8sWBy%%b^VnG90LrOeQb4Y7})P2!z;yyey6XU
z_i2w$ux^+h8L&m)c(j?n(r*%`zPIR6yfZPp*aG+*cjz8p&-^mioxCf8>wu5gFgkyP
zey`txa@J^Vir|&T=YIxiJKI#|KExJ%pUdW%%-y6f)m#aD(6w2=b7?r@WBXn7
zub9{2=-3?ip3id5lf3m#lOJBq1o~aUcHXBwcK-ecwkT#7TG;e3X;(>8-=fmMH?6bs
zx!&n6^gH`~MRXkwe7@(aan7bi`QKGJ@M<-nZy~0QhxT;NzsZIzT7P9bCYtNYCwcY2
z1N9xJ0Uv#abZU)?(|daK>HBnF2fl2U-YY?=`uSdM4G-4?Huw7R_|W_3&VR!ZoqDeS
z6A&+}*ZxGWx)vpe1A4#XA>e~+dd~3{;JiBMTnp$KqYt~KQ~lE$og3~^AspP=l814g
zYK@ey@0VO{Y1iQ%-IQ82?eDwq(0thPsSUDBi0<8hzW?ScM)XechL&daEjb+2ZyM=>uL1vW?@d|q?EHV__3#Y$Tzx2
zd`)Hp3(N=yPq5@+JU-6!Whyq=#;xYyyxn)CsV8mz0w5myh>t>_LsN$>!K0q)BLC<<
z%h~)}n)b0x1D`Ywz7WJYZ?pdn+cMLp$EIB~*yVh#Ag#T$wbqUQ0QiUvz0))+tu3z7
zQKsere9rlP3;m_N&w_uNN41?NipP()IV0>^KSO-t?GVo9_qIYs<`!W{Y%LCi@w)(P8k@lSdehGZU$C>Eu
z+clQ5^_=sMp6VulJqYIc;!z&G@b4KQ-XGZP|AxGo*ZuUe8{NA1yUEhN-;=)ZF$nE@
z5b$vyayNSWx;~upHDA3C@cB-zo*Ne4ZYel;kR|`(@#Fnkjcs4Bv~Mx#3w^JXc3lD7
z0$leUy7$<(R~r@~#}3WQX@0bm+J51eVBvvl9c!KP;epWi3a7_RVnI>Wd477l3*dDeAT`d+&C
z_575f`GW_6iODout&3kTURPiHw58UCyIza&FLdgD-H?m
zn-R|F-s)Ol%QvN81PcExM#?-YqrES*^-r4gwAaoKIdKEJR!&oH8Pj0cs3Vgo!3=d6=iC(9Ln4bJPmAP`fEPyrM>n8?bo_2$M>OUUbCVDxP$$=*Zhbh
zer4r)?craiCwvt3-<
z)(?HuVm?gI3Cy$6LWD}XyP@J#XX2w1%z{#TileN0BXKTbZUX46hv0F9};
zwP!b()}svM_n?v-Nqsg0nuF_B@4Pb2877&K`#e0!^Gt9-ZUb^Cz;@ejx|=@lA@VwX
zXPY+CGqQVfaN!K{4%ByU(li})dOgT<-RKoRTBEg78e44B=o$*L%mW#oIseX;O&xOD
zf0FXM{G**t2EE#|ll)Tht>n^{vgo2-%YiRt^h+mSbvmc(()zCJ3_qR+^iGrEyUq4C
z@~z<7CR=^ja6m@;_58$jAF>|pq`8$&ZJ2cKYSOQ2TkkN~!bkz0zRQrs(Jht^cypRpdFAfIuGlPzs@B+ytQsU73zFDKo=&g0rRjCyK(
z_E1W{#C>G5um0P{ti-hN;#ol7I<)CCOj><=)cUt25{=0rzz)UvX&LLGxvb4|6u(SX
z+DG>jdT*#(j7auXFcPt0oJ4*11zL-2!+D#u(w+O;&k?7-nvqkAk^ltAuupx+4>HzIez+CPH2SKoUk|`t#mIX>`}o1-@$KkOb?;2uYaFX@xTTGW
zc)D*Yzh95#*N%<51KkJ4ZMWIiGm+BQGrySj*3#HXP`9Q4?
z!d~4+UI1+C8c(meuxc#QjZh9{a93lI{ejQ5zIyL>PLkQQ_qZizwEkkdBza91&M5{O^-UGM)l`a6F2nzmjE=-r3-buwvR@2(y=NdAr6
zitTz1n&-Vp`98+2Y^
z{|xX`kaP`5b6(${cscOMib{3d18{dua2qh3cD>d2Uv)1RFE-exowaWF5s<_U-IE*$
zmWi)rlnuZM>hXLajwjVO&3XA`#{sDB(3l8!p9y?EU)OuT%Y09rc2*y+5J0sVke<H!JJ+TjKGdeSI53&r?Twj8{|}!e2c<
zyv1XT`~uy5{f+see3?`ZT-F-K<3XNxMdEQHJ!gVdlFF>kyYm42T^IO##(o|8M|$2D
zF6&*9FMv4D^X}h-KD|fajtrHijvj!&8-w2h*Y{XP-vV?G-8YdtIy2!UJk}bmi$LDE
zi09YZ1g+7j?za;B?&>uB-5fML#>lDY9_g_qJl6B|D?yy&dH406=GmYWzisb|k7d&X
zceN&dJMbVd*L{~;y^r!1P`0WUYL9pf>L71iwCDdVI(GvjeGT&6nDBQ8;OnGkdjfsq*znrr_D=MU{51~#YCNLvRvTWs+-e?JeUyHC#jf$I
z)IB`_e>EO?CD1*Q%h)iwu0gM}-x=vyp^_$myPDVfGH~^Lq&>!T&vhP{2TJON@|iXB
zlKb>*SI@4dX}{AS{8fx-UA(VvGoFs_ksnXe26{g70U$27^V`+2-sSu>*a&oL?&=&K
zkZ-`opa!l3dY3P8eP|RThqLwZ?uh2J-k>r@{f{=#wd&Qt)q1U@xRQST&d-Km)ZN~!
zzkC7oy!9;bIEedCaguni6UE38o?=Ab(<=4%cAHN0yh9tPjr4xiZ$P|#eC$6=8J_{V
zR(h^kdDT;QU6-~8-vCM94_Jt7y>7LD!+O8!D4=V;8AG_*-iywz<#)4f*krWD8sJjk
zYfKW4w|`R3`9K^Qi8T(?Q`e!j!JEO4KrcV*-n8d@5*${Hyc_t4k^e#O%EQL>to5Ni
zRshEUeUmuOXJ7kTW2|q|zX_}ZhH6}>`T&i+<^#>Ex8Fl`^Xtz^pX%BX#faV!^bsQ$
zqPLo}kAjLe(RFSIa2x2>ey(M@_tLoZwO~y!kgDrP+zt!DDCfkVwP4?6<=>A
zZ@3r5$eY=^eugN0hg30QJl)#TZsN`}!6hK?{X-W1bju^YDt5&&arjd3C7@?69|rFS
z?*w{J_^r|Yd)XcjP6QtZdftCIP=BEQO8R`nL3=&)Z0JKE)$gRWTBQ4)I1F9~Tz{kS
zNp!we`m4WXJwQ8Z{JA^01+=$yb)4QOdhYRgumM=s(GJdt!$51-U9XLQ0-djPVB*lK
zpiOlT@a*w_9@B$vs2A2SrG4d$-cF$wiDCHFgz{cPMpx^Vt{frM?BhCk!kM3(+#Q6u8
zR{$pim*2!zjJ!BrPPO0L1Mougtvi6vfd&}%`!C%?=|1yV&~xonZx8xO0hcvye?1Vd
zUG*jUecq9OM>lJW!52MO+ZmhzG!Hv0v7&xLbHbV{*7K5q`R);X*0}v{hcWVdbd6`_
zNR_YoF3?PPq<*CaZUT>ie%=e&mi<@k)mpK`z+5meG11OJ_`D&|I$c-&$j#`gzO&ix
z=nTj3O3xhiy9{fAJ;6u7_2BQoma{(7--kVlhhxC@Ky!8(YFy4N@OfqMRfjQh7P?9^
z<|?PxvsoqH0o{vj0}ckC0N(+(f(OBqKyyMa<6#N<^jzXm@GEd7&@=VdfO#O*I`eEb
zE=Ml-yd3xla4~Mzn%}+4QM1vo0*-24O!sB#YjmH#3wRYc8k_)51zJ<`4e(uXHMj;`
z8{vCwuK*VTJ-0p)ybbINbg#D|P`@y+_ey!00H^h?)!Tud{pG#ix(gjM^4e78_u~P0
zu6}3={FF3YTH&koPy*e}ax`98!^LC_MnTw*b0N
z%6hN$6nQruO6OFSsyu)P;P?9Ah8!`nZ{^6!1HsjKiKx?-;J#*LZNN+Nz^{eczJmA6u#K3g$9B@21ADjc`gV`?h
zS2`*WR34~2P@Eo;V`H<-iI{9*Bx_m|lhq?xvl=m(5jB;z
zWQ&`!=~00#nJKPyrnOgRH~O0lGji0@U}WQMGE+OrXSB&ehlM#KV>k#C#Y{1$nzDMB
zCH#LfNZ*vz;x1ur*(G@+qJ7MQ7GY7&M`VPrBhNFCN?N_h=r$`)k|
zc1^z8*jQBKprR8>Wn^r}b-Z+G;Jk6|MKYb3)G>cG_5;pDGOEy|NrQ8NS&n|9GT4g$j>S@4Ew4z{2rF-7CI%#up*jv_3tJwO46n&Cp{&u2
zD~XnhJTck0&Y3@Xl>PAk`jjdJXD5xU)@;}?Yb~g6n6EaadV#kmOunhr3o1As$(BU2
zB_?~=)Pc?=Q41|LCQ(5g8psw$RbOO?F+~=(Uei5P9%=>o7DaApnAWHAEg4qv*D&@X
z!`VT;g^>+)Bja>SHW}orHJiAmR6)K*E4+dF7MegVzu6QRy#Gb}4x5~WtYP=ibk
z^BI}qt|c1}bjD?Y;IK$`-TLUxR#MO?$~^1v*W>I{6IKYS^cvMa`y7memlo8fj|2
z&a%nCPGvInMw^Pc2!HRL$3Hh>o(z*$ZiJQesPxPfaw2
z3BjL{HR7_UA=+eWzVL!X&W^IEk=kU9AYarFiy~X1@;b{xJ@qi(WMF4AUvF7$Y)roy
zIWZ+)JJZLtFXA10#Zpp>u-#ji$~}#{Yq1v~9ps
z6}?b=#dw{Q)3i0Rp!;h?4NwmqT95J>*(B-7FgAnD6dCCyl1%liW6>C=g09%eBB#}+
z$_)7e-_`JOET18Cpu8pHbUiR3blRj^Gt3v<7Suy71nn5eBp>6DqKr&uCUicOEtRYh
zx+OR>uG~h(P9tzJHLJ-nfhy??6qt)P%8@OWsz4@#ql;+dw8e5xB%4^eD6D$WAk&wM
z)-Bl*d02lqZ5lETgM4y&^KX$(1$Q!$EV}Y5LBJ-_CCt}|d=lgh*c6wU!X!o2M36er
zsf%;#k5l7;mpaI5foviwZ|ZGp9mfP74Dw-iOXboAY-%X90vTqrYyQNTh7t!d%$_ik
z&@q8`JIE+u+Cq6Zkn#U`E1w**NEHrcwRXpxASW7GyJMs#l+~AUOiR`f1)6`gsQ55n
zV@l=gIHr}4>P|MZ1&(RSsM2^#7KKt|3ss7>yei+yhb&eJRlX&|p|REtSb=a#5>q56
zCt9-F6hk?R$?8)KjgH2`VjEKojgBIjsZv-XN3Ax3|8b9UB(tM@s?ubbY3b6ZIBK&Vbz;#TEIri`4{r9cIQCpcG^OcxLRPYLE4qI@zY`U})iBMv1A
zIw>QY2rgEkh(EDZj}k#P|Af9&he
z$h1%CVSlRw{u-e$B&sUNaVQBdavY8a$2GhYlZBQ>tym{dTo$xNm`w#tk?BNOT2P6}
zcs^6Gw&+NdQHhD9d=!=}t96mpyT}?{WDH^wZDIVJC|irn(YvGOR(=r_WxM$
B_Dlc(
literal 0
HcmV?d00001
diff --git a/docs/src/images/format-review.png b/docs/docs/images/format-review.png
similarity index 100%
rename from docs/src/images/format-review.png
rename to docs/docs/images/format-review.png
diff --git a/docs/src/images/format-suggestion.png b/docs/docs/images/format-suggestion.png
similarity index 100%
rename from docs/src/images/format-suggestion.png
rename to docs/docs/images/format-suggestion.png
diff --git a/docs/theme/favicon.png b/docs/docs/images/logo.png
similarity index 100%
rename from docs/theme/favicon.png
rename to docs/docs/images/logo.png
diff --git a/docs/src/images/step-summary.png b/docs/docs/images/step-summary.png
similarity index 100%
rename from docs/src/images/step-summary.png
rename to docs/docs/images/step-summary.png
diff --git a/docs/src/images/tidy-review.png b/docs/docs/images/tidy-review.png
similarity index 100%
rename from docs/src/images/tidy-review.png
rename to docs/docs/images/tidy-review.png
diff --git a/docs/src/index.md b/docs/docs/index.md
similarity index 59%
rename from docs/src/index.md
rename to docs/docs/index.md
index 9a774e8..627e8a7 100644
--- a/docs/src/index.md
+++ b/docs/docs/index.md
@@ -1,10 +1,10 @@
-[file-annotations]: cli.md#-a---file-annotations
-[thread-comments]: cli.md#-g---thread-comments
-[step-summary]: cli.md#-w---step-summary
-[tidy-review]: cli.md#-d---tidy-review
-[format-review]: cli.md#-m---format-review
+[file-annotations]: cli.md#-a-file-annotations
+[thread-comments]: cli.md#-g-thread-comments
+[step-summary]: cli.md#-w-step-summary
+[tidy-review]: cli.md#-d-tidy-review
+[format-review]: cli.md#-m-format-review
[format-annotations-preview]: images/annotations-clang-format.png
[tidy-annotations-preview]: images/annotations-clang-tidy.png
@@ -14,4 +14,9 @@
[format-review-preview]: images/format-review.png
[format-suggestion-preview]: images/format-suggestion.png
-{{#include ../../README.md:16:}}
+[cli-doc]: cli.md
+
+{%
+ include "../../README.md"
+ start=""
+%}
diff --git a/docs/docs/node.md b/docs/docs/node.md
new file mode 100644
index 0000000..19b522d
--- /dev/null
+++ b/docs/docs/node.md
@@ -0,0 +1,6 @@
+# Node.js Binding
+
+{%
+ include "../../node-binding/README.md"
+ start=""
+%}
diff --git a/docs/src/permissions.md b/docs/docs/permissions.md
similarity index 81%
rename from docs/src/permissions.md
rename to docs/docs/permissions.md
index 2fab227..299a5cb 100644
--- a/docs/src/permissions.md
+++ b/docs/docs/permissions.md
@@ -4,7 +4,7 @@
This is an exhaustive list of required permissions organized by features.
-> [!important]
+> [!IMPORTANT]
> The `GITHUB_TOKEN` environment variable should be supplied when running on a private repository.
> Otherwise the runner does not not have the privileges needed for the features mentioned here.
>
@@ -15,8 +15,8 @@ This is an exhaustive list of required permissions organized by features.
## File Changes
-When using [`--files-changed-only`](cli.md#-f---files-changed-only) or
-[`--lines-changed-only`](cli.md#-l---lines-changed-only) to get the list
+When using [`--files-changed-only`](cli.md#-f-files-changed-only) or
+[`--lines-changed-only`](cli.md#-l-lines-changed-only) to get the list
of file changes for a CI event, the following permissions are needed:
### Push
@@ -51,7 +51,7 @@ the repository is not checked out before running cpp-linter.
## Thread Comments
-The [`--thread-comments`](cli.md#-g---thread-comments) feature requires the following permissions:
+The [`--thread-comments`](cli.md#-g-thread-comments) feature requires the following permissions:
### Push
@@ -78,7 +78,7 @@ For [`pull_request` events][pr-events].
## Pull Request Reviews
-The [`tidy-review`](cli.md#-d---tidy-review), [`format-review`](cli.md#-m---format-review), and [`passive-reviews`](cli.md#-r---passive-reviews) features require the following permissions:
+The [`tidy-review`](cli.md#-d-tidy-review), [`format-review`](cli.md#-m-format-review), and [`passive-reviews`](cli.md#-r-passive-reviews) features require the following permissions:
```yaml
permissions:
diff --git a/docs/src/pr-review-caveats.md b/docs/docs/pr-review-caveats.md
similarity index 95%
rename from docs/src/pr-review-caveats.md
rename to docs/docs/pr-review-caveats.md
index 26d0f98..955bf33 100644
--- a/docs/src/pr-review-caveats.md
+++ b/docs/docs/pr-review-caveats.md
@@ -5,12 +5,12 @@
[hiding a comment]: https://docs.github.com/en/communities/moderating-comments-and-conversations/managing-disruptive-comments#hiding-a-comment
[resolve a conversation]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/commenting-on-a-pull-request#resolving-conversations
-[tidy-review]: cli.md#-d---tidy-review
-[format-review]: cli.md#-m---format-review
-[lines-changed-only]: cli.md#-l---lines-changed-only
-[style]: cli.md#-s---style
+[tidy-review]: cli.md#-d-tidy-review
+[format-review]: cli.md#-m-format-review
+[lines-changed-only]: cli.md#-l-lines-changed-only
+[style]: cli.md#-s-style
-> [!note]
+> [!NOTE]
> This information is specific to GitHub Pull Requests (often abbreviated as "PR").
While the Pull Request review feature has been diligently tested, there are still some caveats to
@@ -23,7 +23,7 @@ By default, the bot cannot approve Pull Request changes, only request more chang
This will show as a warning in the workflow logs if the given token (set to the
environment variable `GITHUB_TOKEN`) isn't configured with the proper permissions.
-> [!important]
+> [!IMPORTANT]
> Refer to the GitHub documentation for [repository settings][] or [organization settings][]
> about adjusting the required permissions for GitHub Actions's `secrets.GITHUB_TOKEN`.
>
@@ -50,7 +50,7 @@ Clang-tidy and clang-format suggestions are shown in 1 Pull Request review.
Also, the outdated review's summary comment is not automatically hidden.
To reduce the Pull Request's thread noise, users interaction is required.
-> [!important]
+> [!IMPORTANT]
> Refer to GitHub's documentation about [hiding a comment][].
> Hiding a Pull Request review's summary comment will not resolve the suggestions in the diff.
> Please also refer to [resolve a conversation][] to collapse outdated or duplicate suggestions
@@ -58,7 +58,7 @@ Clang-tidy and clang-format suggestions are shown in 1 Pull Request review.
GitHub REST API does not provide a way to hide comments or mark review suggestions as resolved.
-> [!tip]
+> [!TIP]
> We do support an environment variable named `CPP_LINTER_PR_REVIEW_SUMMARY_ONLY`.
> If the variable is set to `true`, then the review only contains a summary comment
> with no suggestions posted in the diff.
diff --git a/docs/docs/python.md b/docs/docs/python.md
new file mode 100644
index 0000000..87b2a73
--- /dev/null
+++ b/docs/docs/python.md
@@ -0,0 +1,6 @@
+# Python Binding
+
+{%
+ include "../../py-binding/README.md"
+ start=""
+%}
diff --git a/docs/docs/stylesheets/extra.css b/docs/docs/stylesheets/extra.css
new file mode 100644
index 0000000..abd602f
--- /dev/null
+++ b/docs/docs/stylesheets/extra.css
@@ -0,0 +1,241 @@
+th {
+ background-color: var(--md-default-fg-color--lightest);
+}
+
+.md-header {
+ background-color: #4051b5;
+}
+
+.md-typeset .admonition.important, .md-typeset details.important {
+ border-color: #00b8d4;
+}
+
+.md-typeset .important > .admonition-title::before, .md-typeset .important > summary::before {
+ background-color: #00b8d4;
+ -webkit-mask-image: var(--md-admonition-icon--info);
+ mask-image: var(--md-admonition-icon--info);
+}
+
+.md-typeset .important > .admonition-title, .md-typeset .important > summary {
+ background-color: #00b8d41a;
+}
+
+@keyframes heart {
+
+ 0%,
+ 40%,
+ 80%,
+ to {
+ transform: scale(1)
+ }
+
+ 20%,
+ 60% {
+ transform: scale(1.15)
+ }
+}
+
+.md-typeset .mdx-heart {
+ animation: heart 1s infinite
+}
+
+.md-typeset .mdx-badge {
+ font-size: .85em
+}
+
+.md-typeset .mdx-badge--heart {
+ color: #ff4281;
+}
+
+.md-typeset .mdx-badge--heart.twemoji {
+ animation: heart 1s infinite
+}
+
+.md-typeset .mdx-badge--right {
+ float: right;
+ margin-left: .35em
+}
+
+[dir=ltr] .md-typeset .mdx-badge__icon {
+ border-top-left-radius: .1rem
+}
+
+[dir=rtl] .md-typeset .mdx-badge__icon {
+ border-top-right-radius: .1rem
+}
+
+[dir=ltr] .md-typeset .mdx-badge__icon {
+ border-bottom-left-radius: .1rem
+}
+
+[dir=rtl] .md-typeset .mdx-badge__icon {
+ border-bottom-right-radius: .1rem
+}
+
+.md-typeset .mdx-badge__icon {
+ background: var(--md-accent-fg-color--transparent);
+ padding: .2rem
+}
+
+.md-typeset .mdx-badge__icon:last-child {
+ border-radius: .1rem
+}
+
+[dir=ltr] .md-typeset .mdx-badge__text {
+ border-top-right-radius: .1rem
+}
+
+[dir=rtl] .md-typeset .mdx-badge__text {
+ border-top-left-radius: .1rem
+}
+
+[dir=ltr] .md-typeset .mdx-badge__text {
+ border-bottom-right-radius: .1rem
+}
+
+[dir=rtl] .md-typeset .mdx-badge__text {
+ border-bottom-left-radius: .1rem
+}
+
+.md-typeset .mdx-badge__text {
+ box-shadow: 0 0 0 1px inset var(--md-accent-fg-color--transparent);
+ padding: .2rem .3rem
+}
+
+.md-typeset .mdx-social {
+ height: min(27rem, 80vw);
+ position: relative
+}
+
+.md-typeset .mdx-social:hover .mdx-social__image {
+ background-color: #e4e4e40d
+}
+
+.md-typeset .mdx-social__layer {
+ margin-top: 4rem;
+ position: absolute;
+ transform-style: preserve-3d;
+ transition: .25s cubic-bezier(.7, 0, .3, 1)
+}
+
+.md-typeset .mdx-social__layer:hover .mdx-social__label {
+ opacity: 1
+}
+
+.md-typeset .mdx-social__layer:hover .mdx-social__image {
+ background-color: #7f7f7ffc
+}
+
+.md-typeset .mdx-social__layer:hover~.mdx-social__layer {
+ opacity: 0
+}
+
+.md-typeset .mdx-social__image {
+ box-shadow: -.25rem .25rem .5rem #0000000d;
+ transform: rotate(-40deg) skew(15deg, 15deg) scale(.7);
+ transition: all .25s
+}
+
+.md-typeset .mdx-social__image img {
+ display: block
+}
+
+.md-typeset .mdx-social__label {
+ background-color: var(--md-default-fg-color--light);
+ color: var(--md-default-bg-color);
+ display: block;
+ opacity: 0;
+ padding: .2rem .4rem;
+ position: absolute;
+ transition: all .25s
+}
+
+.md-typeset .mdx-social:hover .mdx-social__layer:nth-child(6) {
+ transform: translateY(-30px)
+}
+
+.md-typeset .mdx-social:hover .mdx-social__layer:nth-child(5) {
+ transform: translateY(-20px)
+}
+
+.md-typeset .mdx-social:hover .mdx-social__layer:nth-child(4) {
+ transform: translateY(-10px)
+}
+
+.md-typeset .mdx-social:hover .mdx-social__layer:nth-child(3) {
+ transform: translateY(0)
+}
+
+.md-typeset .mdx-social:hover .mdx-social__layer:nth-child(2) {
+ transform: translateY(10px)
+}
+
+.md-typeset .mdx-social:hover .mdx-social__layer:first-child {
+ transform: translateY(20px)
+}
+
+.md-typeset .mdx-social:hover .mdx-social__layer:nth-child(0) {
+ transform: translateY(30px)
+}
+
+.md-banner {
+ color: var(--md-footer-fg-color--lighter)
+}
+
+.md-banner strong {
+ white-space: nowrap
+}
+
+.md-banner a,
+.md-banner strong {
+ color: var(--md-footer-fg-color)
+}
+
+.md-banner a:focus,
+.md-banner a:hover {
+ color: currentcolor
+}
+
+.md-banner a:focus .twemoji,
+.md-banner a:hover .twemoji {
+ background-color: var(--md-footer-fg-color);
+ box-shadow: none
+}
+
+.md-banner .twemoji {
+ border-radius: 100%;
+ box-shadow: inset 0 0 0 .05rem currentcolor;
+ display: inline-block;
+ height: 1.2rem;
+ padding: .25rem;
+ transition: all .25s;
+ vertical-align: bottom;
+ width: 1.2rem
+}
+
+.md-banner .twemoji svg {
+ display: block;
+ max-height: none
+}
+
+/* annotation buttons' pulse animation */
+a.md-annotation__index {
+ border-radius: 2.2ch;
+}
+
+@keyframes pulse {
+ 0% {
+ box-shadow: 0 0 0 0 var(--md-accent-fg-color);
+ transform: scale(.95)
+ }
+
+ 75% {
+ box-shadow: 0 0 0 .625em transparent;
+ transform: scale(1)
+ }
+
+ to {
+ box-shadow: 0 0 0 0 transparent;
+ transform: scale(.95)
+ }
+}
diff --git a/docs/gen_cli_doc.py b/docs/gen_cli_doc.py
new file mode 100644
index 0000000..6011987
--- /dev/null
+++ b/docs/gen_cli_doc.py
@@ -0,0 +1,36 @@
+from pathlib import Path
+from typing import Dict, Any
+import yaml
+import mkdocs_gen_files
+from cli_gen import generate_cli_doc
+
+FILENAME = "cli.md"
+
+VERSION_DISCLAIMER = """
+!!! quote "v1.x vs v2.x"
+
+ - v1.x was written in pure python
+ - v2.x was written in rust (with python and node.js bindings)
+
+ Version 2.x is intended to be backwards compatible, but a complete
+ rewrite in rust prompted a major version bump.
+
+ The minimum versions (badges) specified here hyperlink to different repositories.
+ Anything established in v2.x will correspond to the rust project.
+ Anything established in v1.4.6 or later (before v2.0.0) will correspond to the pure
+ python project. Anything established before v1.4.6 will correspond to pure python
+ sources in the cpp-linter-action project.
+
+"""
+
+with mkdocs_gen_files.open(FILENAME, "w") as io_doc:
+ options_versions = Path(__file__).parent / "cli.yml"
+ versions: Dict[str, Any] = yaml.safe_load(options_versions.read_bytes())
+
+ print("# Command Line Interface\n", file=io_doc)
+ print(VERSION_DISCLAIMER, file=io_doc)
+ doc = generate_cli_doc(versions["inputs"])
+ # print(doc)
+ print(doc, file=io_doc)
+
+mkdocs_gen_files.set_edit_path(FILENAME, "gen_io_doc.py")
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
new file mode 100644
index 0000000..591606b
--- /dev/null
+++ b/docs/mkdocs.yml
@@ -0,0 +1,98 @@
+site_name: Cpp-Linter
+site_description: "Documentation for the cpp-linter package."
+site_url: "https://cpp-linter.github.io/cpp-linter-rs"
+repo_url: "https://github.com/cpp-linter/cpp-linter-rs"
+repo_name: "cpp-linter/cpp-linter-rs"
+edit_uri: "edit/main/docs/docs/"
+nav:
+ - index.md
+ - cli.md
+ - pr-review-caveats.md
+ - permissions.md
+ - python.md
+ - node.md
+ - changelog.md
+
+theme:
+ name: material
+ features:
+ - navigation.top
+ - content.tabs.link
+ - content.tooltips
+ - content.code.annotate
+ - content.code.copy
+ - content.action.view
+ - content.action.edit
+ - navigation.footer
+ - search.suggest
+ - search.share
+ - navigation.tracking
+ - toc.follow
+ logo: images/logo.png
+ favicon: images/favicon.ico
+ icon:
+ repo: fontawesome/brands/github
+ palette:
+ # Palette toggle for automatic mode
+ - media: "(prefers-color-scheme)"
+ primary: blue
+ accent: cyan
+ toggle:
+ icon: material/brightness-auto
+ name: Switch to light mode
+
+ # Palette toggle for light mode
+ - media: "(prefers-color-scheme: light)"
+ scheme: default
+ primary: blue
+ accent: cyan
+ toggle:
+ icon: material/lightbulb-outline
+ name: Switch to dark mode
+
+ # Palette toggle for dark mode
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ primary: blue
+ accent: cyan
+ toggle:
+ icon: material/lightbulb
+ name: Switch to system preference
+extra:
+ social:
+ - icon: fontawesome/brands/github
+ link: https://github.com/cpp-linter/cpp-linter
+
+extra_css:
+ - stylesheets/extra.css
+
+plugins:
+ - search
+ - include-markdown
+ - gen-files:
+ scripts:
+ - gen_cli_doc.py
+
+markdown_extensions:
+ - pymdownx.superfences
+ - pymdownx.tabbed:
+ alternate_style: true
+ - pymdownx.emoji:
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
+ - toc:
+ permalink: true
+ - pymdownx.highlight:
+ linenums_style: pymdownx-inline
+ - pymdownx.inlinehilite
+ - pymdownx.snippets:
+ check_paths: true
+ - pymdownx.tasklist:
+ custom_checkbox: true
+ - attr_list
+ - admonition
+ - markdown_gfm_admonition
+
+# Hooks
+hooks:
+ - badge_hook.py
diff --git a/docs/pyproject.toml b/docs/pyproject.toml
new file mode 100644
index 0000000..d2a7da3
--- /dev/null
+++ b/docs/pyproject.toml
@@ -0,0 +1,17 @@
+[build-system]
+requires = ["maturin>=1.4,<2.0"]
+build-backend = "maturin"
+
+[project]
+name = "cli-gen"
+description = "Generate cpp-linter CLI doc from rust src."
+version = "0.0.0"
+readme = "README.md"
+license = {text = "MIT License"}
+requires-python = ">=3.7"
+authors = [
+ { name = "Brendan Doherty", email = "2bndy5@gmail.com" },
+]
+
+[tool.maturin]
+features = ["pyo3/extension-module"]
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 0000000..9024916
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,6 @@
+markdown-gfm-admonition==0.1.1
+mkdocs==1.6.1
+mkdocs-gen-files==0.5.0
+mkdocs-include-markdown-plugin==6.2.2
+mkdocs-material==9.5.39
+pyyaml==6.0.2
diff --git a/docs/src/CHANGELOG.md b/docs/src/CHANGELOG.md
deleted file mode 100644
index ce53563..0000000
--- a/docs/src/CHANGELOG.md
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-{{#include ../../CHANGELOG.md}}
diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md
deleted file mode 100644
index c240a27..0000000
--- a/docs/src/SUMMARY.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Summary
-
-
-
-- [Introduction](./index.md)
-- [Command Line Interface](./cli.md)
-- [Token Permissions](./permissions.md)
-- [Pull Request Review Caveats](./pr-review-caveats.md)
-- [Python Binding](./python.md)
-- [Node.js Binding](./node.md)
-- [Change Log](./CHANGELOG.md)
diff --git a/docs/src/lib.rs b/docs/src/lib.rs
new file mode 100644
index 0000000..9ef7a3e
--- /dev/null
+++ b/docs/src/lib.rs
@@ -0,0 +1,125 @@
+//! This exposes a function in python, so a mkdocs plugin can use it to generates the CLI document.
+//! For actual library/binary source code look in cpp-linter folder.
+use std::collections::HashMap;
+
+use cpp_linter::cli;
+use pyo3::{exceptions::PyValueError, prelude::*};
+
+const GROUPS_ORDER: [&str; 5] = [
+ "General options",
+ "Source options",
+ "Clang-format options",
+ "Clang-tidy options",
+ "Feedback options",
+];
+
+#[pyfunction]
+fn generate_cli_doc(metadata: HashMap>>) -> PyResult {
+ let mut out = String::new();
+ let mut command = cli::get_arg_parser();
+ out.push_str(
+ format!(
+ "```text title=\"Usage\"\n{}\n```\n",
+ command
+ .render_usage()
+ .to_string()
+ .trim_start_matches("Usage: ")
+ )
+ .as_str(),
+ );
+
+ out.push_str("\n## Commands\n");
+ for cmd in command.get_subcommands() {
+ out.push_str(format!("\n### `{}`\n\n", cmd.get_name()).as_str());
+ out.push_str(
+ format!(
+ "{}\n",
+ &cmd.get_about()
+ .ok_or(PyValueError::new_err(format!(
+ "{} command has no help message",
+ cmd.get_name()
+ )))?
+ .to_string()
+ .trim()
+ )
+ .as_str(),
+ );
+ }
+
+ out.push_str("## Arguments\n");
+ for arg in command.get_positionals() {
+ out.push_str(format!("\n### `{}`\n\n", arg.get_id().as_str()).as_str());
+ if let Some(help) = arg.get_help() {
+ out.push_str(format!("{}\n", help.to_string().trim()).as_str());
+ }
+ }
+
+ // reorganize groups according to GROUPS_ORDER
+ let mut ordered = Vec::with_capacity(command.get_groups().count());
+ for group in GROUPS_ORDER {
+ let group_obj = command
+ .get_groups()
+ .find(|arg_group| arg_group.get_id().as_str() == group)
+ .ok_or(PyValueError::new_err(format!(
+ "{} not found in command's groups",
+ group
+ )))?;
+ ordered.push(group_obj.to_owned());
+ }
+
+ for group in ordered {
+ out.push_str(format!("\n## {}\n", group.get_id()).as_str());
+ for arg_id in group.get_args() {
+ let arg = command
+ .get_arguments()
+ .find(|a| *a.get_id() == *arg_id)
+ .ok_or(PyValueError::new_err(format!(
+ "arg {} in group {} not found in command",
+ arg_id.as_str(),
+ group.get_id().as_str()
+ )))?;
+ let long_name = arg.get_long().ok_or(PyValueError::new_err(format!(
+ "Failed to get long name of argument with id {}",
+ arg_id.as_str()
+ )))?;
+ out.push_str(
+ format!(
+ "\n### `-{}, --{}`\n\n",
+ arg.get_short().ok_or(PyValueError::new_err(format!(
+ "Failed to get short name for argument with id {}",
+ arg_id.as_str()
+ )))?,
+ long_name
+ )
+ .as_str(),
+ );
+ if let Some(map) = metadata.get(long_name) {
+ if let Some(val) = map.get("minimum-version") {
+ out.push_str(format!("\n", val).as_str());
+ }
+ if let Some(val) = map.get("required-permission") {
+ out.push_str(format!("\n", val).as_str());
+ }
+ if map.contains_key("experimental") {
+ out.push_str("\n");
+ }
+ }
+ let default = arg.get_default_values();
+ if let Some(default_value) = default.first() {
+ out.push_str(format!("\n\n", default_value).as_str());
+ } else {
+ out.push('\n');
+ }
+ if let Some(help) = &arg.get_help() {
+ out.push_str(format!("{}\n", help.to_string().trim()).as_str());
+ }
+ }
+ }
+ Ok(out)
+}
+
+#[pymodule]
+pub fn cli_gen(m: &Bound<'_, PyModule>) -> PyResult<()> {
+ m.add_function(wrap_pyfunction!(generate_cli_doc, m)?)?;
+ Ok(())
+}
diff --git a/docs/src/main.rs b/docs/src/main.rs
deleted file mode 100644
index fcd99af..0000000
--- a/docs/src/main.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-//! This is a preprocessor for mdbook that generates the CLI document.
-//! For actual library/binary source code look in cpp-linter folder.
-
-extern crate clap;
-use clap::{Arg, ArgMatches, Command};
-extern crate mdbook;
-use mdbook::errors::Error;
-use mdbook::preprocess::{CmdPreprocessor, Preprocessor};
-extern crate semver;
-extern crate serde_json;
-use semver::{Version, VersionReq};
-use std::io;
-use std::process;
-
-extern crate cpp_linter;
-
-use cli_gen_lib::CliGen;
-
-pub fn make_app() -> Command {
- Command::new("cli-gen")
- .about("A mdbook preprocessor which generates a doc of CLI options")
- .subcommand(
- Command::new("supports")
- .arg(Arg::new("renderer").required(true))
- .about("Check whether a renderer is supported by this preprocessor"),
- )
-}
-
-fn handle_preprocessing(pre: &dyn Preprocessor) -> Result<(), Error> {
- let (ctx, book) = CmdPreprocessor::parse_input(io::stdin())?;
-
- let book_version = Version::parse(&ctx.mdbook_version)?;
- let version_req = VersionReq::parse(mdbook::MDBOOK_VERSION)?;
-
- if !version_req.matches(&book_version) {
- eprintln!(
- "Warning: The {} plugin was built against version {} of mdbook, \
- but we're being called from version {}",
- pre.name(),
- mdbook::MDBOOK_VERSION,
- ctx.mdbook_version
- );
- }
-
- let processed_book = pre.run(&ctx, book)?;
- serde_json::to_writer(io::stdout(), &processed_book)?;
-
- Ok(())
-}
-
-fn handle_supports(pre: &dyn Preprocessor, sub_args: &ArgMatches) -> ! {
- let renderer = sub_args
- .get_one::("renderer")
- .expect("Required argument");
- let supported = pre.supports_renderer(renderer);
-
- // Signal whether the renderer is supported by exiting with 1 or 0.
- if supported {
- process::exit(0);
- } else {
- process::exit(1);
- }
-}
-
-fn main() {
- let matches = make_app().get_matches();
-
- // Users will want to construct their own preprocessor here
- let preprocessor = CliGen {};
-
- if let Some(sub_args) = matches.subcommand_matches("supports") {
- handle_supports(&preprocessor, sub_args);
- } else if let Err(e) = handle_preprocessing(&preprocessor) {
- eprintln!("{}", e);
- process::exit(1);
- }
-}
-
-mod cli_gen_lib {
- use std::path::PathBuf;
-
- use mdbook::book::Book;
- use mdbook::preprocess::{Preprocessor, PreprocessorContext};
-
- use cpp_linter::cli;
-
- pub struct CliGen;
-
- impl CliGen {
- fn generate_cli(groups_order: &Option>) -> String {
- let mut out = String::new();
- let command = cli::get_arg_parser();
- out.push_str(format!("\n{}\n\n", "# Command Line Interface").as_str());
- out.push_str("\n");
- out.push_str("\n## Commands\n");
- for cmd in command.get_subcommands() {
- out.push_str(format!("\n### `{}`\n\n", cmd.get_name()).as_str());
- out.push_str(
- format!("{}\n", &cmd.get_about().unwrap().to_string().trim()).as_str(),
- );
- }
- out.push_str("## Arguments\n");
- for arg in command.get_positionals() {
- out.push_str(format!("\n### `{}`\n\n", arg.get_id().as_str()).as_str());
- if let Some(help) = arg.get_help() {
- out.push_str(format!("{}\n", help.to_string().trim()).as_str());
- }
- }
- let arg_groups = if let Some(groups) = groups_order {
- eprintln!("ordering groups into {:?}", groups);
- let mut ordered = Vec::with_capacity(command.get_groups().count());
- for group in groups {
- let mut group_obj = None;
- for arg_group in command.get_groups() {
- if arg_group.get_id().as_str() == group.as_str() {
- group_obj = Some(arg_group.clone());
- }
- }
- ordered.push(
- group_obj
- .unwrap_or_else(|| panic!("{} not found in command's groups", group)),
- );
- }
- ordered
- } else {
- command.get_groups().map(|g| g.to_owned()).collect()
- };
- for group in arg_groups {
- out.push_str(format!("\n## {}\n", group.get_id()).as_str());
- for arg_id in group.get_args() {
- let mut arg_match = command.get_arguments().filter(|a| *a.get_id() == *arg_id);
- let arg = arg_match.next().unwrap_or_else(|| {
- panic!(
- "arg {} expected in group {}",
- arg_id.as_str(),
- group.get_id().as_str()
- )
- });
- out.push_str(
- format!(
- "\n### `-{}, --{}`\n\n",
- &arg.get_short().unwrap(),
- &arg.get_long().unwrap()
- )
- .as_str(),
- );
- let default = arg.get_default_values();
- if !default.is_empty() {
- out.push_str("Default");
- assert_eq!(default.len(), 1);
- out.push_str(
- format!("{:?}
\n\n", default.first().unwrap())
- .as_str(),
- );
- }
- if let Some(help) = &arg.get_help() {
- out.push_str(format!("{}\n", help.to_string().trim()).as_str());
- }
- }
- }
- out
- }
- }
-
- impl Preprocessor for CliGen {
- fn name(&self) -> &str {
- "cli-gen"
- }
-
- fn run(&self, ctx: &PreprocessorContext, book: Book) -> mdbook::errors::Result {
- let mut altered = book.clone();
- let groups_order = match ctx
- .config
- .get_preprocessor("cli-gen")
- .unwrap()
- .get("groups-order")
- {
- Some(val) => val.clone().as_array_mut().map(|v| {
- v.iter_mut()
- .map(|o| o.to_string().trim_matches('"').to_string())
- .collect()
- }),
- None => None,
- };
- altered.for_each_mut(|item| {
- if let mdbook::BookItem::Chapter(chap) = item {
- if chap
- .path
- .clone()
- .is_some_and(|p| p == PathBuf::from("cli.md"))
- {
- chap.content = CliGen::generate_cli(&groups_order);
- }
- }
- });
- Ok(altered)
- }
-
- fn supports_renderer(&self, renderer: &str) -> bool {
- matches!(renderer, "html" | "markdown")
- }
- }
-}
diff --git a/docs/src/node.md b/docs/src/node.md
deleted file mode 100644
index 2423e30..0000000
--- a/docs/src/node.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Node.js Binding
-
-{{#include ../../node-binding/README.md:2:}}
diff --git a/docs/src/python.md b/docs/src/python.md
deleted file mode 100644
index 870ca3e..0000000
--- a/docs/src/python.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Python Binding
-
-{{#include ../../py-binding/README.md:2:}}
diff --git a/docs/theme/pagetoc.css b/docs/theme/pagetoc.css
deleted file mode 100644
index eff428b..0000000
--- a/docs/theme/pagetoc.css
+++ /dev/null
@@ -1,63 +0,0 @@
-@media only screen {
- main {
- position: relative;
- }
-
- .sidetoc {
- margin-left: auto;
- margin-right: auto;
- }
-
- .pagetoc {
- width: auto;
- word-wrap: normal;
- }
-
- .pagetoc a {
- color: var(--sidebar-fg) !important;
- display: block;
- padding-left: 10px;
- text-align: left;
- text-decoration: none;
- margin-block-start: 0.6em;
- }
-
- .pagetoc a:hover,
- .pagetoc a.active {
- color: var(--sidebar-active) !important;
- }
-
- .pagetoc .active {
- color: var(--sidebar-active);
- }
-
- .pagetoc .pagetoc-H2 {
- padding-left: 20px;
- }
-
- .pagetoc .pagetoc-H3 {
- padding-left: 40px;
- }
-
- .pagetoc .pagetoc-H4 {
- padding-left: 60px;
- }
-
- .pagetoc .pagetoc-H5 {
- display: none;
- }
-
- .pagetoc .pagetoc-H6 {
- display: none;
- }
-
- ol.chapter a {
- color: var(--sidebar-fg);
- text-decoration: none;
- }
-
- ol.chapter a.active {
- color: var(--sidebar-active);
- text-decoration: none;
- }
-}
diff --git a/docs/theme/pagetoc.js b/docs/theme/pagetoc.js
deleted file mode 100644
index a9d7a91..0000000
--- a/docs/theme/pagetoc.js
+++ /dev/null
@@ -1,99 +0,0 @@
-let scrollTimeout;
-
-const listenActive = () => {
- const elems = document.querySelector(".pagetoc").children;
- [...elems].forEach((el) => {
- el.addEventListener("click", () => {
- clearTimeout(scrollTimeout);
- [...elems].forEach((el) => el.classList.remove("active"));
- el.classList.add("active");
- // Prevent scroll updates for a short period
- // eslint-disable-next-line no-async-operation
- scrollTimeout = setTimeout(() => {
- scrollTimeout = null;
- }, 100); // Adjust timing as needed
- });
- });
-};
-
-const getPagetoc = () => {
- return document.querySelector(".pagetoc") || autoCreatePagetoc();
-};
-
-const autoCreatePagetoc = () => {
- const chapter = document.querySelector(
- "body nav#sidebar.sidebar li.chapter-item.expanded a.active"
- );
- const content = Object.assign(document.createElement("div"), {
- className: "content-wrap",
- });
- content.appendChild(chapter.cloneNode(true));
- const divAddedToc = Object.assign(document.createElement("div"), {
- className: "sidetoc",
- });
- const navAddedToc = Object.assign(document.createElement("nav"), {
- className: "pagetoc",
- });
- divAddedToc.appendChild(navAddedToc);
- content.appendChild(divAddedToc);
- chapter.replaceWith(content);
- return document.querySelector(".pagetoc");
-};
-
-const updateFunction = () => {
- if (scrollTimeout) return; // Skip updates if within the cooldown period from a click
- const headers = [...document.getElementsByClassName("header")];
- const scrolledY = window.scrollY;
-
- // Find the last header that is above the current scroll position
- let headerOffsets = headers.filter((el) => scrolledY >= el.offsetTop);
- const lastHeader = headerOffsets.reverse().shift();
-
- const pagetocLinks = [...document.querySelector(".pagetoc").children];
- pagetocLinks.forEach((link) => link.classList.remove("active"));
-
- if (lastHeader) {
- const activeLink = pagetocLinks.find(
- (link) => lastHeader.href === link.href
- );
- if (activeLink) activeLink.classList.add("active");
- }
-};
-function getHeaderText(header) {
- let text = header.textContent;
- if (text === "") {
- let sibling = header.nextSibling;
- let maxIterations = 100;
- while (sibling != null && maxIterations > 0) {
- text += sibling.textContent;
- sibling = sibling.nextSibling;
- maxIterations--;
- }
- if (maxIterations === 0) {
- console.warn(
- "Possible circular reference in DOM when extracting header text"
- );
- }
- }
- return text;
-}
-
-const onLoad = () => {
- const pagetoc = getPagetoc();
- var headers = [...document.getElementsByClassName("header")];
- headers.shift();
- headers.forEach((header) => {
- const text = getHeaderText(header);
- const link = Object.assign(document.createElement("a"), {
- textContent: text,
- href: header.href,
- className: `pagetoc-${header.parentElement.tagName}`,
- });
- pagetoc.appendChild(link);
- });
- updateFunction();
- listenActive();
- window.addEventListener("scroll", updateFunction);
-};
-
-window.addEventListener("load", onLoad);
diff --git a/justfile b/justfile
index 000d796..1601b35 100644
--- a/justfile
+++ b/justfile
@@ -34,12 +34,12 @@ lcov:
# serve docs
[group("docs")]
docs open='':
- mdbook serve docs {{ open }}
+ mkdocs serve --config-file docs/mkdocs.yml {{ open }}
# build docs
[group("docs")]
-docs-build open='':
- mdbook build docs {{ open }}
+docs-build:
+ mkdocs build --config-file docs/mkdocs.yml
# rust docs
[group("docs")]
diff --git a/node-binding/README.md b/node-binding/README.md
index a71f6bd..2452c35 100644
--- a/node-binding/README.md
+++ b/node-binding/README.md
@@ -1,5 +1,5 @@
# cpp-linter
-
+
The node.js binding for the [cpp-linter-rs][this] rust project
(built using [napi-rs](https://napi.rs) and [yarn](https://yarnpkg.com)).
diff --git a/py-binding/README.md b/py-binding/README.md
index 2eacd73..45fcb59 100644
--- a/py-binding/README.md
+++ b/py-binding/README.md
@@ -1,5 +1,5 @@
# cpp-linter
-
+
The python binding for the [cpp-linter-rs][this] rust project
(built using [pyo3](https://pyo3.rs) and [maturin]).
From 57ff2288df99b4dd8a6adae850b7396d5b00bc71 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sun, 29 Sep 2024 10:55:08 -0700
Subject: [PATCH 2/5] Update docs/gen_cli_doc.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
docs/gen_cli_doc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/gen_cli_doc.py b/docs/gen_cli_doc.py
index 6011987..3378cf5 100644
--- a/docs/gen_cli_doc.py
+++ b/docs/gen_cli_doc.py
@@ -33,4 +33,4 @@
# print(doc)
print(doc, file=io_doc)
-mkdocs_gen_files.set_edit_path(FILENAME, "gen_io_doc.py")
+mkdocs_gen_files.set_edit_path(FILENAME, "gen_cli_doc.py")
From 83782a661643d607e66e6eef39ff07246098ce98 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sun, 29 Sep 2024 11:13:15 -0700
Subject: [PATCH 3/5] Update comment in docs/src/lib.rs
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
docs/src/lib.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/src/lib.rs b/docs/src/lib.rs
index 9ef7a3e..20e0cce 100644
--- a/docs/src/lib.rs
+++ b/docs/src/lib.rs
@@ -1,4 +1,4 @@
-//! This exposes a function in python, so a mkdocs plugin can use it to generates the CLI document.
+//! This exposes a function in Python, so an mkdocs plugin can use it to generate the CLI document.
//! For actual library/binary source code look in cpp-linter folder.
use std::collections::HashMap;
From 459ae239878a42dd42fc0c8cc8cfdd67ac4ed8fc Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sun, 29 Sep 2024 11:14:10 -0700
Subject: [PATCH 4/5] update name of CI job's step
---
.github/workflows/build-docs.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index 7efcd44..c416df0 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -57,7 +57,7 @@ jobs:
run: |
pip install -r docs/requirements.txt
pip install --force-reinstall -v docs/
- - name: Build book
+ - name: Build docs
working-directory: docs
run: mkdocs build
- name: Upload docs build as artifact
From 2184391f8604bfb921f3c9dc16d0ccc6e7016a2b Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sun, 29 Sep 2024 11:33:28 -0700
Subject: [PATCH 5/5] add to social icons
---
docs/mkdocs.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index 591606b..a968d56 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -62,6 +62,12 @@ extra:
social:
- icon: fontawesome/brands/github
link: https://github.com/cpp-linter/cpp-linter
+ - icon: fontawesome/brands/python
+ link: https://pypi.org/project/cpp-linter/
+ - icon: fontawesome/brands/npm
+ link: https://www.npmjs.com/package/@cpp-linter/cpp-linter
+ - icon: simple/rust
+ link: https://crates.io/crates/cpp-linter
extra_css:
- stylesheets/extra.css