Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Gmail: add `gmail watch pull` for Pub/Sub pull subscription consumers with hook retry support. (#700) — thanks @joshp123.
- Docs: add `--tab` and `--all-tabs` to `docs raw` for inspecting specific or complete multi-tab document content. (#697) — thanks @sebsnyk.
- Docs: add tab-aware table, image, heading, and paragraph enumerators with structured and plain output. (#719) — thanks @sebsnyk.
- Docs: style locally rendered fenced Markdown blocks with Roboto Mono, dark-green text, and existing paragraph shading. (#676, #724) — thanks @TurboTheTurtle.

### Fixed

Expand Down
7 changes: 6 additions & 1 deletion internal/cmd/docs_find_replace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,11 +536,16 @@ func TestDocsFindReplace_MarkdownCodeBlockStartsFreshParagraphWhenInline(t *test
}
reqs := batchCalls[0].Requests
if len(reqs) != 5 {
t.Fatalf("expected delete, insert, reset, code font, and code shading requests, got %#v", reqs)
t.Fatalf("expected delete, insert, reset, code text style, and code shading requests, got %#v", reqs)
}
if got := reqs[1].InsertText; got == nil || got.Location.Index != 7 || got.Text != "\nline1"+docsSoftLineBreak+"line2\n" {
t.Fatalf("unexpected insert request: %#v", got)
}
if got := reqs[3].UpdateTextStyle; got == nil || got.Range.StartIndex != 8 || got.Range.EndIndex != 20 {
t.Fatalf("unexpected code text style request: %#v", got)
} else {
assertFencedCodeTextStyle(t, got)
}
if got := reqs[4].UpdateParagraphStyle; got == nil || got.Range.StartIndex != 8 || got.Range.EndIndex != 20 {
t.Fatalf("unexpected code shading request: %#v", got)
}
Expand Down
24 changes: 20 additions & 4 deletions internal/cmd/docs_formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ import (
// same textRun, which lets fenced code blocks keep one shaded paragraph.
const docsSoftLineBreak = "\v"

const (
docsFencedCodeFontFamily = "Roboto Mono"
docsFencedCodeColorRed = 0.09411764705882353
docsFencedCodeColorGreen = 0.5019607843137255
docsFencedCodeColorBlue = 0.2196078431372549
)

// Debug flag for markdown formatter
var debugMarkdown = false

Expand Down Expand Up @@ -92,14 +99,14 @@ func MarkdownToDocsRequests(elements []MarkdownElement, baseIndex int64, tabID s
// Embedded line breaks become soft line breaks (vertical tab) so
// Docs keeps them inside one paragraph, which lets us apply a
// single paragraph-level background shading across the whole block
// instead of emitting one Courier-styled paragraph per source line.
// instead of emitting one styled paragraph per source line.
// See #594.
codeBody := strings.ReplaceAll(el.Content, "\n", docsSoftLineBreak)
codeContent := codeBody + "\n"
plainText.WriteString(codeContent)
charOffset += utf16Len(codeContent)

// Apply monospace font to entire code block text run.
// Apply fenced code styling to the entire code block text run.
requests = append(requests, &docs.Request{
UpdateTextStyle: &docs.UpdateTextStyleRequest{
Range: &docs.Range{
Expand All @@ -109,11 +116,20 @@ func MarkdownToDocsRequests(elements []MarkdownElement, baseIndex int64, tabID s
},
TextStyle: &docs.TextStyle{
WeightedFontFamily: &docs.WeightedFontFamily{
FontFamily: "Courier New",
FontFamily: docsFencedCodeFontFamily,
Weight: 400,
},
ForegroundColor: &docs.OptionalColor{
Color: &docs.Color{
RgbColor: &docs.RgbColor{
Red: docsFencedCodeColorRed,
Green: docsFencedCodeColorGreen,
Blue: docsFencedCodeColorBlue,
},
},
},
},
Fields: "weightedFontFamily",
Fields: "weightedFontFamily,foregroundColor",
},
})

Expand Down
46 changes: 39 additions & 7 deletions internal/cmd/docs_formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func TestMarkdownToDocsRequests_MixedListChildrenStayNested(t *testing.T) {
// TestMarkdownToDocsRequests_AppendBulletsAndCode is a regression test for
// #594. The append path used to inline literal "• " glyphs for bullet lists
// (leaving paragraphs as NORMAL_TEXT) and split fenced code blocks into one
// Courier-styled NORMAL_TEXT paragraph per source line with no contiguous
// monospace-styled NORMAL_TEXT paragraph per source line with no contiguous
// shading. The fix routes bullets through CreateParagraphBullets and joins
// code-block lines with vertical-tab soft breaks so the whole block is one
// shaded paragraph.
Expand Down Expand Up @@ -318,12 +318,18 @@ func TestMarkdownToDocsRequests_AppendBulletsAndCode(t *testing.T) {
// - 1 CreateParagraphBullets for the numbered item
// - 1 UpdateParagraphStyle with paragraph-level shading covering the
// code block
// - 1 UpdateTextStyle for Courier on the code block range
// - 1 UpdateTextStyle for fenced code font/color on the code block range
codeOffset := strings.Index(text, "line 1")
if codeOffset < 0 {
t.Fatalf("test markdown output does not contain code block text: %q", text)
}
codeStart := int64(1 + utf16Len(text[:codeOffset]))
codeEnd := codeStart + int64(utf16Len("line 1"+docsSoftLineBreak+"line 2"+docsSoftLineBreak+"line 3\n"))
var (
bulletDisc int
bulletNumbered int
codeShading int
codeMonospace int
codeTextStyle int
bulletPrefixText bool
)
for _, r := range requests {
Expand All @@ -344,8 +350,10 @@ func TestMarkdownToDocsRequests_AppendBulletsAndCode(t *testing.T) {
if r.UpdateTextStyle != nil &&
r.UpdateTextStyle.TextStyle != nil &&
r.UpdateTextStyle.TextStyle.WeightedFontFamily != nil &&
r.UpdateTextStyle.TextStyle.WeightedFontFamily.FontFamily == "Courier New" {
codeMonospace++
r.UpdateTextStyle.Range.StartIndex == codeStart &&
r.UpdateTextStyle.Range.EndIndex == codeEnd {
assertFencedCodeTextStyle(t, r.UpdateTextStyle)
codeTextStyle++
}
if r.InsertText != nil && strings.Contains(r.InsertText.Text, "• ") {
bulletPrefixText = true
Expand All @@ -361,10 +369,34 @@ func TestMarkdownToDocsRequests_AppendBulletsAndCode(t *testing.T) {
if codeShading != 1 {
t.Errorf("expected exactly 1 paragraph shading request for the code block, got %d", codeShading)
}
if codeMonospace < 1 {
t.Errorf("expected at least 1 Courier New text style request for the code block, got %d", codeMonospace)
if codeTextStyle != 1 {
t.Errorf("expected exactly 1 fenced code text style request, got %d", codeTextStyle)
}
if bulletPrefixText {
t.Errorf("unexpected literal bullet glyph inside an InsertText request")
}
}

func assertFencedCodeTextStyle(t *testing.T, got *docs.UpdateTextStyleRequest) {
t.Helper()
if got == nil {
t.Fatal("missing fenced code text style request")
}
if got.Fields != "weightedFontFamily,foregroundColor" {
t.Fatalf("fenced code fields = %q, want weightedFontFamily,foregroundColor", got.Fields)
}
style := got.TextStyle
if style == nil {
t.Fatal("missing fenced code text style")
}
if style.WeightedFontFamily == nil || style.WeightedFontFamily.FontFamily != docsFencedCodeFontFamily || style.WeightedFontFamily.Weight != 400 {
t.Fatalf("unexpected fenced code font: %#v", style.WeightedFontFamily)
}
if style.ForegroundColor == nil || style.ForegroundColor.Color == nil || style.ForegroundColor.Color.RgbColor == nil {
t.Fatalf("missing fenced code foreground color: %#v", style.ForegroundColor)
}
rgb := style.ForegroundColor.Color.RgbColor
if rgb.Red != docsFencedCodeColorRed || rgb.Green != docsFencedCodeColorGreen || rgb.Blue != docsFencedCodeColorBlue {
t.Fatalf("fenced code foreground = %#v, want #188038", rgb)
}
}
7 changes: 6 additions & 1 deletion internal/cmd/docs_write_markdown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,14 +795,19 @@ func TestDocsWrite_MarkdownAppendStartsStyledBlocksOnFreshParagraph(t *testing.T
}
reqs := batchRequests[0]
if len(reqs) != 4 {
t.Fatalf("expected insert, bullet, code font, and code shading requests, got %#v", reqs)
t.Fatalf("expected insert, bullet, code text style, and code shading requests, got %#v", reqs)
}
if got := reqs[0].InsertText; got == nil || got.Location.Index != 9 || got.Text != "\nItem\n\nline 1"+docsSoftLineBreak+"line 2\n" {
t.Fatalf("unexpected markdown insert: %#v", got)
}
if got := reqs[1].CreateParagraphBullets; got == nil || got.Range.StartIndex != 10 || got.Range.EndIndex != 15 {
t.Fatalf("unexpected bullet request: %#v", got)
}
if got := reqs[2].UpdateTextStyle; got == nil || got.Range.StartIndex != 16 || got.Range.EndIndex != 30 {
t.Fatalf("unexpected code text style request: %#v", got)
} else {
assertFencedCodeTextStyle(t, got)
}
if got := reqs[3].UpdateParagraphStyle; got == nil || got.Range.StartIndex != 16 || got.Range.EndIndex != 30 {
t.Fatalf("unexpected code shading request: %#v", got)
}
Expand Down
Loading