Skip to content

Commit 8ef492f

Browse files
authored
Subcommand to change all headings of a certain type into another (#17)
``` docxtools style-change --help Change styles inside the document Usage: docxtools <IN_FILE> style-change <SEARCH> <REPLACE> [OUT_FILE] Arguments: <SEARCH> The style to look for e.g. 'Heading 1' <REPLACE> The style to replace it with, e.g. 'Heading 2' [OUT_FILE] The output file to write to. If ommitted writing is done to the input file ```
1 parent 6ea821a commit 8ef492f

File tree

14 files changed

+410
-19
lines changed

14 files changed

+410
-19
lines changed

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
name = "docxtools"
33
version = "0.7.1-SNAPSHOT"
44
edition = "2021"
5+
authors = ["David Bosschaert <[email protected]>"]
6+
license = "Apache-2.0"
7+
description = "A command-line tool to work with docx files, for example to make bulk-changes in them without the need to open a word processor."
8+
readme = "README.md"
9+
keywords = ["cli", "docx"]
10+
categories = ["command-line-utilities"]
511

612
[dependencies]
713
regex = "1.9"
@@ -12,6 +18,7 @@ unicode-bom = "2.0"
1218
clap = { version = "4.3.19", features = ["derive"] }
1319
quick-xml = "0.31"
1420
uuid = { version = "1.6", features = ["v4"] }
21+
unicase = "2.7"
1522

1623
[dev-dependencies]
1724
gag = "1.0"

src/bin/main.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ enum Commands {
3535
Replace(ReplaceArgs),
3636

3737
/// Search and replace hyperlinks in the document
38-
ReplaceLinks(ReplaceArgs)
38+
ReplaceLinks(ReplaceArgs),
39+
40+
/// Change styles inside the document
41+
StyleChange(StyleChangeArgs)
3942
}
4043

4144
#[derive(Args)]
@@ -64,6 +67,18 @@ struct ReplaceArgs {
6467
out_file: Option<String>
6568
}
6669

70+
#[derive(Args)]
71+
struct StyleChangeArgs {
72+
/// The style to look for e.g. 'Heading 1'
73+
search: String,
74+
75+
/// The style to replace it with, e.g. 'Heading 2'
76+
replace: String,
77+
78+
/// The output file to write to. If ommitted writing is done to the input file.
79+
out_file: Option<String>
80+
}
81+
6782
fn main() {
6883
let args = Cli::parse();
6984

@@ -92,9 +107,9 @@ fn real_main(args: Cli) -> i32 {
92107
},
93108
Commands::Links(_) => {
94109
XMLUtil::cat_rel_attr (
95-
"Relationship", "Target",
96-
"Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
97-
&temp_dir, &src_file);
110+
"Relationship", "Target",
111+
"Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
112+
&temp_dir, &src_file);
98113
}
99114
Commands::Grep(grep_args) => {
100115
XMLUtil::grep_xml(&temp_dir, &src_file, &grep_args.regex)
@@ -108,6 +123,11 @@ fn real_main(args: Cli) -> i32 {
108123
XMLUtil::replace_rel_attr(&temp_dir, &src_file,
109124
&replace_args.regex, &replace_args.replace,
110125
&replace_args.out_file.as_deref());
126+
},
127+
Commands::StyleChange(args) => {
128+
XMLUtil::change_style(&temp_dir, &src_file,
129+
&args.search, &args.replace,
130+
&args.out_file.as_deref());
111131
}
112132
}
113133

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/><Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/><Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>

src/test/test_tree6/_rels/.rels

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>Normal.dotm</Template><TotalTime>1</TotalTime><Pages>1</Pages><Words>10</Words><Characters>58</Characters><Application>Microsoft Office Word</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><Company></Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>67</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0000</AppVersion></Properties>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title><dc:subject></dc:subject><dc:creator>David Bosschaert</dc:creator><cp:keywords></cp:keywords><dc:description></dc:description><cp:lastModifiedBy>David Bosschaert</cp:lastModifiedBy><cp:revision>2</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2024-01-15T16:23:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2024-01-17T15:40:00Z</dcterms:modified></cp:coreProperties>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/></Relationships>
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
3+
xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex"
4+
xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex"
5+
xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex"
6+
xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex"
7+
xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex"
8+
xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex"
9+
xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex"
10+
xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex"
11+
xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex"
12+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
13+
xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink"
14+
xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d"
15+
xmlns:o="urn:schemas-microsoft-com:office:office"
16+
xmlns:oel="http://schemas.microsoft.com/office/2019/extlst"
17+
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
18+
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
19+
xmlns:v="urn:schemas-microsoft-com:vml"
20+
xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"
21+
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
22+
xmlns:w10="urn:schemas-microsoft-com:office:word"
23+
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
24+
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
25+
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
26+
xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"
27+
xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"
28+
xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"
29+
xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"
30+
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex"
31+
xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
32+
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
33+
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
34+
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14">
35+
<w:body>
36+
<w:p w14:paraId="3831A204" w14:textId="4785353C" w:rsidR="00E45F37" w:rsidRDefault="00E45F37" w:rsidP="00E45F37">
37+
<w:pPr>
38+
<w:pStyle w:val="Heading1"/>
39+
<w:rPr>
40+
<w:lang w:val="en-US"/>
41+
</w:rPr>
42+
</w:pPr>
43+
<w:r>
44+
<w:rPr>
45+
<w:lang w:val="en-US"/>
46+
</w:rPr>
47+
<w:t>Head 1</w:t>
48+
</w:r>
49+
</w:p>
50+
<w:p w14:paraId="38580280" w14:textId="7DC1E065" w:rsidR="00E45F37" w:rsidRPr="00E45F37" w:rsidRDefault="00E45F37" w:rsidP="00E45F37">
51+
<w:pPr>
52+
<w:rPr>
53+
<w:lang w:val="en-US"/>
54+
</w:rPr>
55+
</w:pPr>
56+
<w:r>
57+
<w:rPr>
58+
<w:lang w:val="en-US"/>
59+
</w:rPr>
60+
<w:t>Some paragraph</w:t>
61+
</w:r>
62+
</w:p>
63+
<w:p w14:paraId="0C043509" w14:textId="4DFCB850" w:rsidR="00146782" w:rsidRDefault="00E45F37" w:rsidP="00E45F37">
64+
<w:pPr>
65+
<w:pStyle w:val="Heading1"/>
66+
<w:rPr>
67+
<w:lang w:val="en-US"/>
68+
</w:rPr>
69+
</w:pPr>
70+
<w:r>
71+
<w:rPr>
72+
<w:lang w:val="en-US"/>
73+
</w:rPr>
74+
<w:t>Head 1 again</w:t>
75+
</w:r>
76+
</w:p>
77+
<w:p w14:paraId="7BBCBA98" w14:textId="316E93EB" w:rsidR="00E45F37" w:rsidRDefault="00E45F37" w:rsidP="00E45F37">
78+
<w:pPr>
79+
<w:rPr>
80+
<w:lang w:val="en-US"/>
81+
</w:rPr>
82+
</w:pPr>
83+
<w:r>
84+
<w:rPr>
85+
<w:lang w:val="en-US"/>
86+
</w:rPr>
87+
<w:t>Another paragraph</w:t>
88+
</w:r>
89+
</w:p>
90+
<w:p w14:paraId="399B0D22" w14:textId="77777777" w:rsidR="00E45F37" w:rsidRDefault="00E45F37" w:rsidP="00E45F37">
91+
<w:pPr>
92+
<w:rPr>
93+
<w:lang w:val="en-US"/>
94+
</w:rPr>
95+
</w:pPr>
96+
</w:p>
97+
<w:p w14:paraId="7D716FC9" w14:textId="657DF479" w:rsidR="00E45F37" w:rsidRDefault="00E45F37" w:rsidP="00E45F37">
98+
<w:pPr>
99+
<w:pStyle w:val="Heading2"/>
100+
<w:rPr>
101+
<w:lang w:val="en-US"/>
102+
</w:rPr>
103+
</w:pPr>
104+
<w:r>
105+
<w:rPr>
106+
<w:lang w:val="en-US"/>
107+
</w:rPr>
108+
<w:t>Head 2</w:t>
109+
</w:r>
110+
</w:p>
111+
<w:p w14:paraId="75EAD0DA" w14:textId="6363A11B" w:rsidR="00E45F37" w:rsidRPr="00E45F37" w:rsidRDefault="00E45F37" w:rsidP="00E45F37">
112+
<w:pPr>
113+
<w:pStyle w:val="Heading3"/>
114+
<w:rPr>
115+
<w:lang w:val="en-US"/>
116+
</w:rPr>
117+
</w:pPr>
118+
<w:r>
119+
<w:rPr>
120+
<w:lang w:val="en-US"/>
121+
</w:rPr>
122+
<w:t>Head 3</w:t>
123+
</w:r>
124+
</w:p>
125+
<w:sectPr w:rsidR="00E45F37" w:rsidRPr="00E45F37">
126+
<w:pgSz w:w="11906" w:h="16838"/>
127+
<w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/>
128+
<w:cols w:space="708"/>
129+
<w:docGrid w:linePitch="360"/>
130+
</w:sectPr>
131+
</w:body>
132+
</w:document>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<w:fonts xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh"><w:font w:name="Aptos"><w:panose1 w:val="020B0004020202020204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="20000287" w:usb1="00000003" w:usb2="00000000" w:usb3="00000000" w:csb0="0000019F" w:csb1="00000000"/></w:font><w:font w:name="Times New Roman"><w:panose1 w:val="02020603050405020304"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="E0002EFF" w:usb1="C000785B" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/></w:font><w:font w:name="Aptos Display"><w:panose1 w:val="020B0004020202020204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="20000287" w:usb1="00000003" w:usb2="00000000" w:usb3="00000000" w:csb0="0000019F" w:csb1="00000000"/></w:font></w:fonts>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<w:settings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh"><w:zoom w:percent="100"/><w:proofState w:spelling="clean" w:grammar="clean"/><w:defaultTabStop w:val="720"/><w:characterSpacingControl w:val="doNotCompress"/><w:compat><w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"/><w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="differentiateMultirowTableHeaders" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="useWord2013TrackBottomHyphenation" w:uri="http://schemas.microsoft.com/office/word" w:val="0"/></w:compat><w:rsids><w:rsidRoot w:val="00E45F37"/><w:rsid w:val="00146782"/><w:rsid w:val="00D536E6"/><w:rsid w:val="00E45F37"/></w:rsids><m:mathPr><m:mathFont m:val="Cambria Math"/><m:brkBin m:val="before"/><m:brkBinSub m:val="--"/><m:smallFrac m:val="0"/><m:dispDef/><m:lMargin m:val="0"/><m:rMargin m:val="0"/><m:defJc m:val="centerGroup"/><m:wrapIndent m:val="1440"/><m:intLim m:val="subSup"/><m:naryLim m:val="undOvr"/></m:mathPr><w:themeFontLang w:val="en-IE"/><w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/><w:decimalSymbol w:val="."/><w:listSeparator w:val=","/><w14:docId w14:val="5532AE94"/><w15:chartTrackingRefBased/><w15:docId w15:val="{8DAC41B1-E5E4-7E43-B744-D62C58647593}"/></w:settings>

0 commit comments

Comments
 (0)