Skip to content

Commit 988df94

Browse files
Merge pull request #124 from Financial-Times/feature/UPPSF-6577
add in-numbers section component to content-tree go representation
2 parents 7102d49 + 9b361a7 commit 988df94

File tree

7 files changed

+166
-9
lines changed

7 files changed

+166
-9
lines changed

content_tree.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ const (
8181
TimelineType = "timeline"
8282
TimelineEventType = "timeline-event"
8383
TimelineEventChildType = "timeline-event-child"
84+
85+
DefinitionType = "definition"
86+
InNumbersType = "in-numbers"
8487
)
8588

8689
var (
@@ -402,6 +405,7 @@ type BodyBlock struct {
402405
*CustomCodeComponent
403406
*ClipSet
404407
*Timeline
408+
*InNumbers
405409
}
406410

407411
func (n *BodyBlock) GetType() string {
@@ -472,6 +476,9 @@ func (n *BodyBlock) GetEmbedded() Node {
472476
if n.Timeline != nil {
473477
return n.Timeline
474478
}
479+
if n.InNumbers != nil {
480+
return n.InNumbers
481+
}
475482
return nil
476483
}
477484

@@ -539,6 +546,9 @@ func (n *BodyBlock) GetChildren() []Node {
539546
if n.Timeline != nil {
540547
return n.Timeline.GetChildren()
541548
}
549+
if n.InNumbers != nil {
550+
return n.InNumbers.GetChildren()
551+
}
542552
return nil
543553
}
544554

@@ -677,6 +687,12 @@ func (n *BodyBlock) UnmarshalJSON(data []byte) error {
677687
return err
678688
}
679689
n.Timeline = &v
690+
case InNumbersType:
691+
var v InNumbers
692+
if err := json.Unmarshal(data, &v); err != nil {
693+
return err
694+
}
695+
n.InNumbers = &v
680696
default:
681697
return fmt.Errorf("failed to unmarshal BodyBlock from %s: %w", data, ErrUnmarshalInvalidNode)
682698
}
@@ -727,6 +743,8 @@ func (n *BodyBlock) MarshalJSON() ([]byte, error) {
727743
return json.Marshal(n.ClipSet)
728744
case n.Timeline != nil:
729745
return json.Marshal(n.Timeline)
746+
case n.InNumbers != nil:
747+
return json.Marshal(n.InNumbers)
730748
default:
731749
return []byte(`{}`), nil
732750
}
@@ -777,6 +795,8 @@ func makeBodyBlock(n Node) (*BodyBlock, error) {
777795
return &BodyBlock{ClipSet: n.(*ClipSet)}, nil
778796
case TimelineType:
779797
return &BodyBlock{Timeline: n.(*Timeline)}, nil
798+
case InNumbersType:
799+
return &BodyBlock{InNumbers: n.(*InNumbers)}, nil
780800
default:
781801
return nil, ErrInvalidChildType
782802
}
@@ -2805,3 +2825,53 @@ func makeTimelineEventChild(n Node) (*TimelineEventChild, error) {
28052825
return nil, ErrInvalidChildType
28062826
}
28072827
}
2828+
2829+
type Definition struct {
2830+
Type string `json:"type"`
2831+
Term string `json:"term"`
2832+
Description string `json:"description"`
2833+
}
2834+
2835+
func (d *Definition) GetType() string {
2836+
return d.Type
2837+
}
2838+
2839+
func (d *Definition) GetEmbedded() Node {
2840+
return nil
2841+
}
2842+
2843+
func (d *Definition) GetChildren() []Node {
2844+
return nil
2845+
}
2846+
2847+
func (n *Definition) AppendChild(_ Node) error { return ErrCannotHaveChildren }
2848+
2849+
type InNumbers struct {
2850+
Type string `json:"type"`
2851+
Title string `json:"title,omitempty"`
2852+
Children []*Definition `json:"children"`
2853+
}
2854+
2855+
func (in *InNumbers) GetType() string {
2856+
return in.Type
2857+
}
2858+
2859+
func (in *InNumbers) GetEmbedded() Node {
2860+
return nil
2861+
}
2862+
2863+
func (in *InNumbers) GetChildren() []Node {
2864+
result := make([]Node, len(in.Children))
2865+
for i, v := range in.Children {
2866+
result[i] = v
2867+
}
2868+
return result
2869+
}
2870+
2871+
func (in *InNumbers) AppendChild(child Node) error {
2872+
if child.GetType() != DefinitionType {
2873+
return ErrInvalidChildType
2874+
}
2875+
in.Children = append(in.Children, child.(*Definition))
2876+
return nil
2877+
}

libraries/from-bodyxml/go/html_transformers.go

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ var defaultTransformers = map[string]transformer{
162162
},
163163
"ol": func(ol *etree.Element) contenttree.Node {
164164
dataType := attr(ol, "data-type")
165-
if dataType == "timeline_events" {
165+
if dataType == "timeline-events" {
166166
return newLiftChildrenNode()
167167
}
168168
return &contenttree.List{
@@ -180,7 +180,7 @@ var defaultTransformers = map[string]transformer{
180180
},
181181
"li": func(li *etree.Element) contenttree.Node {
182182
dataType := attr(li, "data-type")
183-
if dataType == "timeline_event" {
183+
if dataType == "timeline-event" {
184184
timelineEventTitle := ""
185185
if h4Element := findChild(li, "h4"); h4Element != nil {
186186
timelineEventTitle = textContent(h4Element)
@@ -337,6 +337,10 @@ var defaultTransformers = map[string]transformer{
337337
}
338338
},
339339
"div": func(div *etree.Element) contenttree.Node {
340+
dataType := attr(div, "data-type")
341+
if dataType == "in-numbers-definition" {
342+
return newLiftChildrenNode()
343+
}
340344
switch attr(div, "class") {
341345
case "n-content-layout":
342346
return &contenttree.Layout{
@@ -357,6 +361,26 @@ var defaultTransformers = map[string]transformer{
357361
return newUnknownNode(attr(div, "class"), div)
358362
}
359363
},
364+
"dl": func(el *etree.Element) contenttree.Node {
365+
return newLiftChildrenNode()
366+
},
367+
"dt": func(dt *etree.Element) contenttree.Node {
368+
dataType := attr(dt, "data-type")
369+
if dataType == "in-numbers-term" {
370+
desc := ""
371+
ddElement := dt.NextSibling()
372+
if ddElement != nil {
373+
desc = textContent(ddElement)
374+
dt.Parent().RemoveChild(ddElement)
375+
}
376+
return &contenttree.Definition{
377+
Type: contenttree.DefinitionType,
378+
Description: desc,
379+
Term: textContent(dt),
380+
}
381+
}
382+
return newUnknownNode("", dt)
383+
},
360384
"section": func(section *etree.Element) contenttree.Node {
361385
switch attr(section, "data-type") {
362386
case "timeline":
@@ -374,6 +398,20 @@ var defaultTransformers = map[string]transformer{
374398
Children: []*contenttree.TimelineEvent{},
375399
}
376400
}
401+
case "in-numbers":
402+
{
403+
var title string
404+
if h3Element := findChild(section, "h3"); h3Element != nil {
405+
title = textContent(h3Element)
406+
//extract title but don't treat like a child element
407+
section.RemoveChild(h3Element)
408+
}
409+
return &contenttree.InNumbers{
410+
Type: contenttree.InNumbersType,
411+
Title: title,
412+
Children: []*contenttree.Definition{},
413+
}
414+
}
377415
}
378416
return newUnknownNode("", section)
379417
},
@@ -382,14 +420,14 @@ var defaultTransformers = map[string]transformer{
382420
},
383421
}
384422

385-
func transformRecommended(rl *etree.Element) contenttree.Node {
423+
func transformRecommended(r *etree.Element) contenttree.Node {
386424
id := ""
387425
teaser := ""
388-
if link := findChild(rl, "content"); link != nil {
389-
id = attr(link, "id")
390-
teaser = textContent(link)
426+
if c := findChild(r, "content"); c != nil {
427+
id = attr(c, "id")
428+
teaser = textContent(c)
391429
}
392-
heading := findChild(rl, "recommended-title")
430+
heading := findChild(r, "recommended-title")
393431
return &contenttree.Recommended{
394432
Type: contenttree.RecommendedType,
395433
ID: id,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<body><p>Lorell</p><section data-type="in-numbers" data-layout-width="full-width"><h3>Ipsum</h3><dl><div data-type="in-numbers-definition"><dt data-type="in-numbers-term">111</dt><dd data-type="in-numbers-description">Stat one</dd></div><div data-type="in-numbers-definition"><dt data-type="in-numbers-term">222</dt><dd data-type="in-numbers-description">Stat two</dd></div><div data-type="in-numbers-definition"><dt data-type="in-numbers-term">333</dt><dd data-type="in-numbers-description">Stat three</dd></div></dl></section><p>Lorell</p></body>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<body><section data-type="timeline" data-layout-width="full-width"><h3>lorem</h3><ol data-type="timeline-events"><li data-type="timeline-event"><h4>ipsum</h4><p>lorem</p><p>ipsum</p><content type="http://www.ft.com/ontology/content/ImageSet" id="a47cfe4c-1f80-4492-9717-93aa65565e37"/></li><li data-type="timeline-event"><h4>lorem</h4><p>ipsum</p></li></ol></section></body>

tests/bodyxml-to-content-tree/input/simple-body-section.xml

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"type": "root",
3+
"body": {
4+
"type": "body",
5+
"children": [
6+
{
7+
"type": "paragraph",
8+
"children": [
9+
{
10+
"type": "text",
11+
"value": "Lorell"
12+
}
13+
]
14+
},
15+
{
16+
"type": "in-numbers",
17+
"title": "Ipsum",
18+
"children": [
19+
{
20+
"type": "definition",
21+
"term": "111",
22+
"description": "Stat one"
23+
},
24+
{
25+
"type": "definition",
26+
"term": "222",
27+
"description": "Stat two"
28+
},
29+
{
30+
"type": "definition",
31+
"term": "333",
32+
"description": "Stat three"
33+
}
34+
]
35+
},
36+
{
37+
"type": "paragraph",
38+
"children": [
39+
{
40+
"type": "text",
41+
"value": "Lorell"
42+
}
43+
]
44+
}
45+
],
46+
"version": 1
47+
}
48+
}

tests/bodyxml-to-content-tree/output/simple-body-section.json renamed to tests/bodyxml-to-content-tree/output/simple-body-section-timeline.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,4 @@
5656
],
5757
"version": 1
5858
}
59-
}
59+
}

0 commit comments

Comments
 (0)