runline 0.7.5 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -135,6 +135,16 @@ const SCOPES = [
|
|
|
135
135
|
"https://www.googleapis.com/auth/documents",
|
|
136
136
|
"https://www.googleapis.com/auth/drive.file",
|
|
137
137
|
];
|
|
138
|
+
function hexToRgbF(hex) {
|
|
139
|
+
const h = hex.replace(/^#/, "");
|
|
140
|
+
const full = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
|
|
141
|
+
const n = parseInt(full, 16);
|
|
142
|
+
return {
|
|
143
|
+
red: ((n >> 16) & 0xff) / 255,
|
|
144
|
+
green: ((n >> 8) & 0xff) / 255,
|
|
145
|
+
blue: (n & 0xff) / 255,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
138
148
|
export default function googleDocs(rl) {
|
|
139
149
|
rl.setName("googleDocs");
|
|
140
150
|
rl.setVersion("0.1.0");
|
|
@@ -635,4 +645,414 @@ export default function googleDocs(rl) {
|
|
|
635
645
|
});
|
|
636
646
|
},
|
|
637
647
|
});
|
|
648
|
+
// ─── Discrete text / paragraph / table formatting ────────────────
|
|
649
|
+
//
|
|
650
|
+
// These wrap individual batchUpdate sub-requests so the agent gets a
|
|
651
|
+
// discoverable surface for the common formatting moves instead of having
|
|
652
|
+
// to assemble a full batchUpdate payload.
|
|
653
|
+
rl.registerAction("document.updateTextStyle", {
|
|
654
|
+
description: "Apply text styling (bold, italic, underline, color, fontSize, fontFamily, link) to a range. Pass `fields` listing which TextStyle properties were set.",
|
|
655
|
+
inputSchema: {
|
|
656
|
+
document: { type: "string", required: true },
|
|
657
|
+
startIndex: { type: "number", required: true },
|
|
658
|
+
endIndex: { type: "number", required: true },
|
|
659
|
+
bold: { type: "boolean", required: false },
|
|
660
|
+
italic: { type: "boolean", required: false },
|
|
661
|
+
underline: { type: "boolean", required: false },
|
|
662
|
+
strikethrough: { type: "boolean", required: false },
|
|
663
|
+
fontSizePt: { type: "number", required: false, description: "Font size in points." },
|
|
664
|
+
fontFamily: { type: "string", required: false },
|
|
665
|
+
foregroundColorHex: { type: "string", required: false, description: "Hex color, e.g. #1A73E8" },
|
|
666
|
+
backgroundColorHex: { type: "string", required: false },
|
|
667
|
+
link: { type: "string", required: false, description: "URL for the linked range." },
|
|
668
|
+
segmentId: { type: "string", required: false, description: "Header/footer/footnote id; omit for the body." },
|
|
669
|
+
},
|
|
670
|
+
async execute(input, ctx) {
|
|
671
|
+
const p = (input ?? {});
|
|
672
|
+
const documentId = extractDocumentId(p.document);
|
|
673
|
+
const ts = {};
|
|
674
|
+
const fields = [];
|
|
675
|
+
if (p.bold !== undefined) {
|
|
676
|
+
ts.bold = p.bold;
|
|
677
|
+
fields.push("bold");
|
|
678
|
+
}
|
|
679
|
+
if (p.italic !== undefined) {
|
|
680
|
+
ts.italic = p.italic;
|
|
681
|
+
fields.push("italic");
|
|
682
|
+
}
|
|
683
|
+
if (p.underline !== undefined) {
|
|
684
|
+
ts.underline = p.underline;
|
|
685
|
+
fields.push("underline");
|
|
686
|
+
}
|
|
687
|
+
if (p.strikethrough !== undefined) {
|
|
688
|
+
ts.strikethrough = p.strikethrough;
|
|
689
|
+
fields.push("strikethrough");
|
|
690
|
+
}
|
|
691
|
+
if (p.fontSizePt !== undefined) {
|
|
692
|
+
ts.fontSize = { magnitude: p.fontSizePt, unit: "PT" };
|
|
693
|
+
fields.push("fontSize");
|
|
694
|
+
}
|
|
695
|
+
if (p.fontFamily) {
|
|
696
|
+
ts.weightedFontFamily = { fontFamily: p.fontFamily };
|
|
697
|
+
fields.push("weightedFontFamily");
|
|
698
|
+
}
|
|
699
|
+
if (p.foregroundColorHex) {
|
|
700
|
+
const c = hexToRgbF(p.foregroundColorHex);
|
|
701
|
+
ts.foregroundColor = { color: { rgbColor: c } };
|
|
702
|
+
fields.push("foregroundColor");
|
|
703
|
+
}
|
|
704
|
+
if (p.backgroundColorHex) {
|
|
705
|
+
const c = hexToRgbF(p.backgroundColorHex);
|
|
706
|
+
ts.backgroundColor = { color: { rgbColor: c } };
|
|
707
|
+
fields.push("backgroundColor");
|
|
708
|
+
}
|
|
709
|
+
if (p.link) {
|
|
710
|
+
ts.link = { url: p.link };
|
|
711
|
+
fields.push("link");
|
|
712
|
+
}
|
|
713
|
+
if (fields.length === 0) {
|
|
714
|
+
throw new Error("googleDocs.document.updateTextStyle: at least one styling property required");
|
|
715
|
+
}
|
|
716
|
+
return runBatchUpdate(ctx, documentId, [
|
|
717
|
+
{
|
|
718
|
+
updateTextStyle: {
|
|
719
|
+
range: {
|
|
720
|
+
startIndex: p.startIndex,
|
|
721
|
+
endIndex: p.endIndex,
|
|
722
|
+
segmentId: p.segmentId,
|
|
723
|
+
},
|
|
724
|
+
textStyle: ts,
|
|
725
|
+
fields: fields.join(","),
|
|
726
|
+
},
|
|
727
|
+
},
|
|
728
|
+
]);
|
|
729
|
+
},
|
|
730
|
+
});
|
|
731
|
+
rl.registerAction("document.updateParagraphStyle", {
|
|
732
|
+
description: "Apply paragraph styling (alignment, named style, indents, spacing, direction) to the paragraphs intersecting the range.",
|
|
733
|
+
inputSchema: {
|
|
734
|
+
document: { type: "string", required: true },
|
|
735
|
+
startIndex: { type: "number", required: true },
|
|
736
|
+
endIndex: { type: "number", required: true },
|
|
737
|
+
alignment: { type: "string", required: false, description: "START | CENTER | END | JUSTIFIED" },
|
|
738
|
+
namedStyleType: { type: "string", required: false, description: "NORMAL_TEXT | TITLE | SUBTITLE | HEADING_1 .. HEADING_6" },
|
|
739
|
+
direction: { type: "string", required: false, description: "LEFT_TO_RIGHT | RIGHT_TO_LEFT" },
|
|
740
|
+
indentFirstLinePt: { type: "number", required: false },
|
|
741
|
+
indentStartPt: { type: "number", required: false },
|
|
742
|
+
indentEndPt: { type: "number", required: false },
|
|
743
|
+
spaceAbovePt: { type: "number", required: false },
|
|
744
|
+
spaceBelowPt: { type: "number", required: false },
|
|
745
|
+
lineSpacing: { type: "number", required: false, description: "Percentage; 100 = single, 150 = 1.5x." },
|
|
746
|
+
segmentId: { type: "string", required: false },
|
|
747
|
+
},
|
|
748
|
+
async execute(input, ctx) {
|
|
749
|
+
const p = (input ?? {});
|
|
750
|
+
const documentId = extractDocumentId(p.document);
|
|
751
|
+
const ps = {};
|
|
752
|
+
const fields = [];
|
|
753
|
+
const pt = (n) => ({ magnitude: n, unit: "PT" });
|
|
754
|
+
if (p.alignment) {
|
|
755
|
+
ps.alignment = p.alignment;
|
|
756
|
+
fields.push("alignment");
|
|
757
|
+
}
|
|
758
|
+
if (p.namedStyleType) {
|
|
759
|
+
ps.namedStyleType = p.namedStyleType;
|
|
760
|
+
fields.push("namedStyleType");
|
|
761
|
+
}
|
|
762
|
+
if (p.direction) {
|
|
763
|
+
ps.direction = p.direction;
|
|
764
|
+
fields.push("direction");
|
|
765
|
+
}
|
|
766
|
+
if (p.indentFirstLinePt !== undefined) {
|
|
767
|
+
ps.indentFirstLine = pt(p.indentFirstLinePt);
|
|
768
|
+
fields.push("indentFirstLine");
|
|
769
|
+
}
|
|
770
|
+
if (p.indentStartPt !== undefined) {
|
|
771
|
+
ps.indentStart = pt(p.indentStartPt);
|
|
772
|
+
fields.push("indentStart");
|
|
773
|
+
}
|
|
774
|
+
if (p.indentEndPt !== undefined) {
|
|
775
|
+
ps.indentEnd = pt(p.indentEndPt);
|
|
776
|
+
fields.push("indentEnd");
|
|
777
|
+
}
|
|
778
|
+
if (p.spaceAbovePt !== undefined) {
|
|
779
|
+
ps.spaceAbove = pt(p.spaceAbovePt);
|
|
780
|
+
fields.push("spaceAbove");
|
|
781
|
+
}
|
|
782
|
+
if (p.spaceBelowPt !== undefined) {
|
|
783
|
+
ps.spaceBelow = pt(p.spaceBelowPt);
|
|
784
|
+
fields.push("spaceBelow");
|
|
785
|
+
}
|
|
786
|
+
if (p.lineSpacing !== undefined) {
|
|
787
|
+
ps.lineSpacing = p.lineSpacing;
|
|
788
|
+
fields.push("lineSpacing");
|
|
789
|
+
}
|
|
790
|
+
if (fields.length === 0) {
|
|
791
|
+
throw new Error("googleDocs.document.updateParagraphStyle: at least one property required");
|
|
792
|
+
}
|
|
793
|
+
return runBatchUpdate(ctx, documentId, [
|
|
794
|
+
{
|
|
795
|
+
updateParagraphStyle: {
|
|
796
|
+
range: { startIndex: p.startIndex, endIndex: p.endIndex, segmentId: p.segmentId },
|
|
797
|
+
paragraphStyle: ps,
|
|
798
|
+
fields: fields.join(","),
|
|
799
|
+
},
|
|
800
|
+
},
|
|
801
|
+
]);
|
|
802
|
+
},
|
|
803
|
+
});
|
|
804
|
+
rl.registerAction("document.updateTableCellStyle", {
|
|
805
|
+
description: "Apply table-cell styling (background color, borders, padding) to a contiguous span of cells. Pass either a single cell via `tableStartLocation+rowIndex+columnIndex`, or a range via `tableStartLocation+rowSpan+columnSpan`.",
|
|
806
|
+
inputSchema: {
|
|
807
|
+
document: { type: "string", required: true },
|
|
808
|
+
tableStartIndex: { type: "number", required: true, description: "The startIndex of the table element." },
|
|
809
|
+
rowIndex: { type: "number", required: true },
|
|
810
|
+
columnIndex: { type: "number", required: true },
|
|
811
|
+
rowSpan: { type: "number", required: false, default: 1 },
|
|
812
|
+
columnSpan: { type: "number", required: false, default: 1 },
|
|
813
|
+
backgroundColorHex: { type: "string", required: false },
|
|
814
|
+
paddingLeftPt: { type: "number", required: false },
|
|
815
|
+
paddingRightPt: { type: "number", required: false },
|
|
816
|
+
paddingTopPt: { type: "number", required: false },
|
|
817
|
+
paddingBottomPt: { type: "number", required: false },
|
|
818
|
+
contentAlignment: { type: "string", required: false, description: "TOP | MIDDLE | BOTTOM" },
|
|
819
|
+
},
|
|
820
|
+
async execute(input, ctx) {
|
|
821
|
+
const p = (input ?? {});
|
|
822
|
+
const documentId = extractDocumentId(p.document);
|
|
823
|
+
const style = {};
|
|
824
|
+
const fields = [];
|
|
825
|
+
const pt = (n) => ({ magnitude: n, unit: "PT" });
|
|
826
|
+
if (p.backgroundColorHex) {
|
|
827
|
+
style.backgroundColor = { color: { rgbColor: hexToRgbF(p.backgroundColorHex) } };
|
|
828
|
+
fields.push("backgroundColor");
|
|
829
|
+
}
|
|
830
|
+
if (p.paddingLeftPt !== undefined) {
|
|
831
|
+
style.paddingLeft = pt(p.paddingLeftPt);
|
|
832
|
+
fields.push("paddingLeft");
|
|
833
|
+
}
|
|
834
|
+
if (p.paddingRightPt !== undefined) {
|
|
835
|
+
style.paddingRight = pt(p.paddingRightPt);
|
|
836
|
+
fields.push("paddingRight");
|
|
837
|
+
}
|
|
838
|
+
if (p.paddingTopPt !== undefined) {
|
|
839
|
+
style.paddingTop = pt(p.paddingTopPt);
|
|
840
|
+
fields.push("paddingTop");
|
|
841
|
+
}
|
|
842
|
+
if (p.paddingBottomPt !== undefined) {
|
|
843
|
+
style.paddingBottom = pt(p.paddingBottomPt);
|
|
844
|
+
fields.push("paddingBottom");
|
|
845
|
+
}
|
|
846
|
+
if (p.contentAlignment) {
|
|
847
|
+
style.contentAlignment = p.contentAlignment;
|
|
848
|
+
fields.push("contentAlignment");
|
|
849
|
+
}
|
|
850
|
+
if (fields.length === 0) {
|
|
851
|
+
throw new Error("googleDocs.document.updateTableCellStyle: at least one style property required");
|
|
852
|
+
}
|
|
853
|
+
return runBatchUpdate(ctx, documentId, [
|
|
854
|
+
{
|
|
855
|
+
updateTableCellStyle: {
|
|
856
|
+
tableRange: {
|
|
857
|
+
tableCellLocation: {
|
|
858
|
+
tableStartLocation: { index: p.tableStartIndex },
|
|
859
|
+
rowIndex: p.rowIndex,
|
|
860
|
+
columnIndex: p.columnIndex,
|
|
861
|
+
},
|
|
862
|
+
rowSpan: p.rowSpan ?? 1,
|
|
863
|
+
columnSpan: p.columnSpan ?? 1,
|
|
864
|
+
},
|
|
865
|
+
tableCellStyle: style,
|
|
866
|
+
fields: fields.join(","),
|
|
867
|
+
},
|
|
868
|
+
},
|
|
869
|
+
]);
|
|
870
|
+
},
|
|
871
|
+
});
|
|
872
|
+
rl.registerAction("document.mergeTableCells", {
|
|
873
|
+
description: "Merge a contiguous block of cells in a table.",
|
|
874
|
+
inputSchema: {
|
|
875
|
+
document: { type: "string", required: true },
|
|
876
|
+
tableStartIndex: { type: "number", required: true },
|
|
877
|
+
rowIndex: { type: "number", required: true },
|
|
878
|
+
columnIndex: { type: "number", required: true },
|
|
879
|
+
rowSpan: { type: "number", required: true },
|
|
880
|
+
columnSpan: { type: "number", required: true },
|
|
881
|
+
},
|
|
882
|
+
async execute(input, ctx) {
|
|
883
|
+
const p = (input ?? {});
|
|
884
|
+
const documentId = extractDocumentId(p.document);
|
|
885
|
+
return runBatchUpdate(ctx, documentId, [
|
|
886
|
+
{
|
|
887
|
+
mergeTableCells: {
|
|
888
|
+
tableRange: {
|
|
889
|
+
tableCellLocation: {
|
|
890
|
+
tableStartLocation: { index: p.tableStartIndex },
|
|
891
|
+
rowIndex: p.rowIndex,
|
|
892
|
+
columnIndex: p.columnIndex,
|
|
893
|
+
},
|
|
894
|
+
rowSpan: p.rowSpan,
|
|
895
|
+
columnSpan: p.columnSpan,
|
|
896
|
+
},
|
|
897
|
+
},
|
|
898
|
+
},
|
|
899
|
+
]);
|
|
900
|
+
},
|
|
901
|
+
});
|
|
902
|
+
rl.registerAction("document.unmergeTableCells", {
|
|
903
|
+
description: "Unmerge a previously merged block of cells.",
|
|
904
|
+
inputSchema: {
|
|
905
|
+
document: { type: "string", required: true },
|
|
906
|
+
tableStartIndex: { type: "number", required: true },
|
|
907
|
+
rowIndex: { type: "number", required: true },
|
|
908
|
+
columnIndex: { type: "number", required: true },
|
|
909
|
+
rowSpan: { type: "number", required: true },
|
|
910
|
+
columnSpan: { type: "number", required: true },
|
|
911
|
+
},
|
|
912
|
+
async execute(input, ctx) {
|
|
913
|
+
const p = (input ?? {});
|
|
914
|
+
const documentId = extractDocumentId(p.document);
|
|
915
|
+
return runBatchUpdate(ctx, documentId, [
|
|
916
|
+
{
|
|
917
|
+
unmergeTableCells: {
|
|
918
|
+
tableRange: {
|
|
919
|
+
tableCellLocation: {
|
|
920
|
+
tableStartLocation: { index: p.tableStartIndex },
|
|
921
|
+
rowIndex: p.rowIndex,
|
|
922
|
+
columnIndex: p.columnIndex,
|
|
923
|
+
},
|
|
924
|
+
rowSpan: p.rowSpan,
|
|
925
|
+
columnSpan: p.columnSpan,
|
|
926
|
+
},
|
|
927
|
+
},
|
|
928
|
+
},
|
|
929
|
+
]);
|
|
930
|
+
},
|
|
931
|
+
});
|
|
932
|
+
rl.registerAction("document.insertInlineImage", {
|
|
933
|
+
description: "Insert an inline image at the given location. `uri` must point to a publicly fetchable image.",
|
|
934
|
+
inputSchema: {
|
|
935
|
+
document: { type: "string", required: true },
|
|
936
|
+
index: { type: "number", required: true },
|
|
937
|
+
uri: { type: "string", required: true },
|
|
938
|
+
widthPt: { type: "number", required: false },
|
|
939
|
+
heightPt: { type: "number", required: false },
|
|
940
|
+
segmentId: { type: "string", required: false },
|
|
941
|
+
},
|
|
942
|
+
async execute(input, ctx) {
|
|
943
|
+
const p = (input ?? {});
|
|
944
|
+
const documentId = extractDocumentId(p.document);
|
|
945
|
+
const pt = (n) => ({ magnitude: n, unit: "PT" });
|
|
946
|
+
const req = {
|
|
947
|
+
location: buildLocation(p.index, p.segmentId),
|
|
948
|
+
uri: p.uri,
|
|
949
|
+
};
|
|
950
|
+
if (p.widthPt !== undefined || p.heightPt !== undefined) {
|
|
951
|
+
req.objectSize = {};
|
|
952
|
+
if (p.widthPt !== undefined)
|
|
953
|
+
req.objectSize.width = pt(p.widthPt);
|
|
954
|
+
if (p.heightPt !== undefined)
|
|
955
|
+
req.objectSize.height = pt(p.heightPt);
|
|
956
|
+
}
|
|
957
|
+
return runBatchUpdate(ctx, documentId, [{ insertInlineImage: req }]);
|
|
958
|
+
},
|
|
959
|
+
});
|
|
960
|
+
rl.registerAction("document.replaceImage", {
|
|
961
|
+
description: "Replace an existing image (identified by its inline-object id) with a new image from a publicly fetchable URI.",
|
|
962
|
+
inputSchema: {
|
|
963
|
+
document: { type: "string", required: true },
|
|
964
|
+
imageObjectId: { type: "string", required: true },
|
|
965
|
+
uri: { type: "string", required: true },
|
|
966
|
+
imageReplaceMethod: { type: "string", required: false, description: "CENTER_CROP (default) | (others as Docs API adds them)" },
|
|
967
|
+
},
|
|
968
|
+
async execute(input, ctx) {
|
|
969
|
+
const p = (input ?? {});
|
|
970
|
+
const documentId = extractDocumentId(p.document);
|
|
971
|
+
return runBatchUpdate(ctx, documentId, [
|
|
972
|
+
{
|
|
973
|
+
replaceImage: {
|
|
974
|
+
imageObjectId: p.imageObjectId,
|
|
975
|
+
uri: p.uri,
|
|
976
|
+
imageReplaceMethod: p.imageReplaceMethod ?? "CENTER_CROP",
|
|
977
|
+
},
|
|
978
|
+
},
|
|
979
|
+
]);
|
|
980
|
+
},
|
|
981
|
+
});
|
|
982
|
+
rl.registerAction("document.insertSectionBreak", {
|
|
983
|
+
description: "Insert a section break at the given location.",
|
|
984
|
+
inputSchema: {
|
|
985
|
+
document: { type: "string", required: true },
|
|
986
|
+
index: { type: "number", required: true },
|
|
987
|
+
sectionType: { type: "string", required: false, description: "CONTINUOUS | NEXT_PAGE. Default CONTINUOUS." },
|
|
988
|
+
segmentId: { type: "string", required: false },
|
|
989
|
+
},
|
|
990
|
+
async execute(input, ctx) {
|
|
991
|
+
const p = (input ?? {});
|
|
992
|
+
const documentId = extractDocumentId(p.document);
|
|
993
|
+
return runBatchUpdate(ctx, documentId, [
|
|
994
|
+
{
|
|
995
|
+
insertSectionBreak: {
|
|
996
|
+
location: buildLocation(p.index, p.segmentId),
|
|
997
|
+
sectionType: p.sectionType ?? "CONTINUOUS",
|
|
998
|
+
},
|
|
999
|
+
},
|
|
1000
|
+
]);
|
|
1001
|
+
},
|
|
1002
|
+
});
|
|
1003
|
+
rl.registerAction("document.updateDocumentStyle", {
|
|
1004
|
+
description: "Update document-level style (page size, margins, page numbers, default direction).",
|
|
1005
|
+
inputSchema: {
|
|
1006
|
+
document: { type: "string", required: true },
|
|
1007
|
+
pageMarginTopPt: { type: "number", required: false },
|
|
1008
|
+
pageMarginBottomPt: { type: "number", required: false },
|
|
1009
|
+
pageMarginLeftPt: { type: "number", required: false },
|
|
1010
|
+
pageMarginRightPt: { type: "number", required: false },
|
|
1011
|
+
pageSizeWidthPt: { type: "number", required: false },
|
|
1012
|
+
pageSizeHeightPt: { type: "number", required: false },
|
|
1013
|
+
useCustomHeaderFooterMargins: { type: "boolean", required: false },
|
|
1014
|
+
},
|
|
1015
|
+
async execute(input, ctx) {
|
|
1016
|
+
const p = (input ?? {});
|
|
1017
|
+
const documentId = extractDocumentId(p.document);
|
|
1018
|
+
const ds = {};
|
|
1019
|
+
const fields = [];
|
|
1020
|
+
const pt = (n) => ({ magnitude: n, unit: "PT" });
|
|
1021
|
+
if (p.pageMarginTopPt !== undefined) {
|
|
1022
|
+
ds.marginTop = pt(p.pageMarginTopPt);
|
|
1023
|
+
fields.push("marginTop");
|
|
1024
|
+
}
|
|
1025
|
+
if (p.pageMarginBottomPt !== undefined) {
|
|
1026
|
+
ds.marginBottom = pt(p.pageMarginBottomPt);
|
|
1027
|
+
fields.push("marginBottom");
|
|
1028
|
+
}
|
|
1029
|
+
if (p.pageMarginLeftPt !== undefined) {
|
|
1030
|
+
ds.marginLeft = pt(p.pageMarginLeftPt);
|
|
1031
|
+
fields.push("marginLeft");
|
|
1032
|
+
}
|
|
1033
|
+
if (p.pageMarginRightPt !== undefined) {
|
|
1034
|
+
ds.marginRight = pt(p.pageMarginRightPt);
|
|
1035
|
+
fields.push("marginRight");
|
|
1036
|
+
}
|
|
1037
|
+
if (p.pageSizeWidthPt !== undefined || p.pageSizeHeightPt !== undefined) {
|
|
1038
|
+
ds.pageSize = {};
|
|
1039
|
+
if (p.pageSizeWidthPt !== undefined)
|
|
1040
|
+
ds.pageSize.width = pt(p.pageSizeWidthPt);
|
|
1041
|
+
if (p.pageSizeHeightPt !== undefined)
|
|
1042
|
+
ds.pageSize.height = pt(p.pageSizeHeightPt);
|
|
1043
|
+
fields.push("pageSize");
|
|
1044
|
+
}
|
|
1045
|
+
if (p.useCustomHeaderFooterMargins !== undefined) {
|
|
1046
|
+
ds.useCustomHeaderFooterMargins = p.useCustomHeaderFooterMargins;
|
|
1047
|
+
fields.push("useCustomHeaderFooterMargins");
|
|
1048
|
+
}
|
|
1049
|
+
if (fields.length === 0) {
|
|
1050
|
+
throw new Error("googleDocs.document.updateDocumentStyle: pass at least one property");
|
|
1051
|
+
}
|
|
1052
|
+
return runBatchUpdate(ctx, documentId, [{ updateDocumentStyle: { documentStyle: ds, fields: fields.join(",") } }]);
|
|
1053
|
+
},
|
|
1054
|
+
});
|
|
1055
|
+
// ─── Small helper for Docs additions ────────────────────────────
|
|
1056
|
+
// (declared at the bottom so it doesn't conflict with the
|
|
1057
|
+
// upstream module-scope `hexToRgb` if one is added later)
|
|
638
1058
|
}
|