diff --git a/html/core/page.go b/html/core/page.go index 1d92edf..230a45b 100644 --- a/html/core/page.go +++ b/html/core/page.go @@ -31,6 +31,7 @@ func (c *Page) WriteHTMLTo(w io.Writer) (int64, error) { +
`) diff --git a/html/core/table.go b/html/core/table.go index bfa533b..2f491e0 100644 --- a/html/core/table.go +++ b/html/core/table.go @@ -18,7 +18,7 @@ func NewTable(tableClass string, content ...Component) *Table { } func (c *Table) WriteHTMLTo(w io.Writer) (int64, error) { - n := appendSprintf(w, ``, c.tableClass) + n := appendSprintf(w, `
`, c.tableClass) n += appendComponent(w, NewComponents(c.content...)) n += appendString(w, "
") diff --git a/html/diff_page.go b/html/diff_page.go index 47c39ad..6c398f7 100644 --- a/html/diff_page.go +++ b/html/diff_page.go @@ -6,6 +6,7 @@ import ( "github.com/elliotchance/gedcom/html/core" "github.com/elliotchance/gedcom/util" "io" + "os" "sort" ) @@ -177,8 +178,32 @@ func (c *DiffPage) WriteHTMLTo(w io.Writer) (int64, error) { precalculatedComparisons = append(precalculatedComparisons, comparison) } + args := os.Args + var rightGedcom string + var leftGedcom string + for index, arg := range args { + if arg == "-right-gedcom" { + rightGedcom = args[index+1] + continue + } + if arg == "-left-gedcom" { + leftGedcom = args[index+1] + continue + } + } + class := "text-center" + attr := map[string]string{} + headerTag := "h5" // The index at the top of the page. - rows := []core.Component{} + rows := []core.Component{ + core.NewTableRow( + core.NewTableCell( + core.NewTag(headerTag, attr, core.NewText(leftGedcom))).Class(class), + core.NewTableCell( + core.NewTag(headerTag, attr, core.NewText("Similarity score"))).Class(class), + core.NewTableCell( + core.NewTag(headerTag, attr, core.NewText(rightGedcom))).Class(class)), + } for _, comparison := range precalculatedComparisons { weightedSimilarity := c.weightedSimilarity(comparison.comparison) @@ -186,36 +211,20 @@ func (c *DiffPage) WriteHTMLTo(w io.Writer) (int64, error) { rightClass := "" switch { - case comparison.comparison.Left != nil && comparison.comparison.Right == nil: + case comparison.comparison.Left != nil && comparison.comparison.Right == nil: //right is missing leftClass = "bg-warning" - case comparison.comparison.Left == nil && comparison.comparison.Right != nil: + case comparison.comparison.Left == nil && comparison.comparison.Right != nil: //left is missing rightClass = "bg-primary" - case weightedSimilarity < 1: + case weightedSimilarity < 1: //neither are missing, but they aren't identical leftClass = "bg-info" rightClass = "bg-info" - case c.filterFlags.HideEqual: + case c.filterFlags.HideEqual: //neither are missing, and they are identical (therefore equal); if user said to hide equal, hide this row continue } - - leftNameAndDates := NewIndividualNameAndDatesLink(comparison.comparison.Left, c.visibility, "") - rightNameAndDates := NewIndividualNameAndDatesLink(comparison.comparison.Right, c.visibility, "") - - left := core.NewTableCell(leftNameAndDates).Class(leftClass) - right := core.NewTableCell(rightNameAndDates).Class(rightClass) - - middle := core.NewTableCell(core.NewText("")) - if weightedSimilarity != 0 { - similarityString := fmt.Sprintf("%.2f%%", weightedSimilarity*100) - middle = core.NewTableCell(core.NewText(similarityString)). - Class("text-center " + leftClass) - } - - tableRow := core.NewTableRow(left, middle, right) - - rows = append(rows, tableRow) + rows = append(rows, c.getRow(comparison, leftClass, rightClass, weightedSimilarity)) } // Individual pages @@ -236,6 +245,24 @@ func (c *DiffPage) WriteHTMLTo(w io.Writer) (int64, error) { ).WriteHTMLTo(w) } +func (c *DiffPage) getRow(comparison *IndividualCompare, leftClass string, rightClass string, weightedSimilarity float64) *core.TableRow { + + leftNameAndDates := NewIndividualNameAndDatesLink(comparison.comparison.Left, c.visibility, "") + rightNameAndDates := NewIndividualNameAndDatesLink(comparison.comparison.Right, c.visibility, "") + + left := core.NewTableCell(leftNameAndDates).Class(leftClass) + right := core.NewTableCell(rightNameAndDates).Class(rightClass) + + middle := core.NewTableCell(core.NewText("")) + if weightedSimilarity != 0 { + similarityString := fmt.Sprintf("%.2f%%", weightedSimilarity*100) + middle = core.NewTableCell(core.NewText(similarityString)). + Class("text-center " + leftClass) + } + + return core.NewTableRow(left, middle, right) +} + func (c *DiffPage) shouldSkip(comparison *IndividualCompare) bool { switch c.show { case DiffPageShowAll: diff --git a/node_diff.go b/node_diff.go index 79bb9a6..c1e471f 100644 --- a/node_diff.go +++ b/node_diff.go @@ -2,29 +2,29 @@ // // CompareNodes recursively compares two nodes. For example: // -// 0 INDI @P3@ | 0 INDI @P4@ -// 1 NAME John /Smith/ | 1 NAME J. /Smith/ -// 1 BIRT | 1 BIRT -// 2 DATE 3 SEP 1943 | 2 DATE Abt. Sep 1943 -// 1 DEAT | 1 BIRT -// 2 PLAC England | 2 DATE 3 SEP 1943 -// 1 BIRT | 1 DEAT -// 2 DATE Abt. Oct 1943 | 2 DATE Aft. 2001 -// | 2 PLAC Surry, England +// 0 INDI @P3@ | 0 INDI @P4@ +// 1 NAME John /Smith/ | 1 NAME J. /Smith/ +// 1 BIRT | 1 BIRT +// 2 DATE 3 SEP 1943 | 2 DATE Abt. Sep 1943 +// 1 DEAT | 1 BIRT +// 2 PLAC England | 2 DATE 3 SEP 1943 +// 1 BIRT | 1 DEAT +// 2 DATE Abt. Oct 1943 | 2 DATE Aft. 2001 +// | 2 PLAC Surry, England // // Produces a *NodeDiff than can be rendered with the String method: // -// LR 0 INDI @P3@ -// L 1 NAME John /Smith/ -// LR 1 BIRT -// L 2 DATE Abt. Oct 1943 -// LR 2 DATE 3 SEP 1943 -// R 2 DATE Abt. Sep 1943 -// LR 1 DEAT -// L 2 PLAC England -// R 2 DATE Aft. 2001 -// R 2 PLAC Surry, England -// R 1 NAME J. /Smith/ +// LR 0 INDI @P3@ +// L 1 NAME John /Smith/ +// LR 1 BIRT +// L 2 DATE Abt. Oct 1943 +// LR 2 DATE 3 SEP 1943 +// R 2 DATE Abt. Sep 1943 +// LR 1 DEAT +// L 2 PLAC England +// R 2 DATE Aft. 2001 +// R 2 PLAC Surry, England +// R 1 NAME J. /Smith/ package gedcom import ( @@ -54,10 +54,10 @@ import ( // considered to be equal because the BirthNode.Equals regards all BirthNodes as // equal (see specific documentation for a complete explanation): // -// BIRT | BIRT | BIRT -// DATE 3 SEP 1943 | DATE 3 SEP 1943 | PLAC England -// BIRT | PLAC England | DATE 3 SEP 1943 -// PLAC England | | BIRT +// BIRT | BIRT | BIRT +// DATE 3 SEP 1943 | DATE 3 SEP 1943 | PLAC England +// BIRT | PLAC England | DATE 3 SEP 1943 +// PLAC England | | BIRT // // However, the semantics of Equals is quite different for other types of nodes. // For example ResidenceNodes are considered equal only if they have the same @@ -92,7 +92,7 @@ type NodeDiff struct { // If you need to be sure the root node are the equal after the comparison, you // can use (this is also nil safe): // -// d.Left.Equals(d.Right) +// d.Left.Equals(d.Right) // // The algorithm to perform the diff is actually very simple: // @@ -110,15 +110,15 @@ type NodeDiff struct { // // Here are two individuals that have slightly different data: // -// 0 INDI @P3@ | 0 INDI @P4@ -// 1 NAME John /Smith/ | 1 NAME J. /Smith/ -// 1 BIRT | 1 BIRT -// 2 DATE 3 SEP 1943 | 2 DATE Abt. Sep 1943 -// 1 DEAT | 1 BIRT -// 2 PLAC England | 2 DATE 3 SEP 1943 -// 1 BIRT | 1 DEAT -// 2 DATE Abt. Oct 1943 | 2 DATE Aft. 2001 -// | 2 PLAC Surry, England +// 0 INDI @P3@ | 0 INDI @P4@ +// 1 NAME John /Smith/ | 1 NAME J. /Smith/ +// 1 BIRT | 1 BIRT +// 2 DATE 3 SEP 1943 | 2 DATE Abt. Sep 1943 +// 1 DEAT | 1 BIRT +// 2 PLAC England | 2 DATE 3 SEP 1943 +// 1 BIRT | 1 DEAT +// 2 DATE Abt. Oct 1943 | 2 DATE Aft. 2001 +// | 2 PLAC Surry, England // // In this case both of the root nodes are different (because of the different // pointer values). The returned left and right will have the respective root @@ -126,18 +126,17 @@ type NodeDiff struct { // // Here is the output, rendered with NodeDiff.String(): // -// LR 0 INDI @P3@ -// L 1 NAME John /Smith/ -// LR 1 BIRT -// L 2 DATE Abt. Oct 1943 -// LR 2 DATE 3 SEP 1943 -// R 2 DATE Abt. Sep 1943 -// LR 1 DEAT -// L 2 PLAC England -// R 2 DATE Aft. 2001 -// R 2 PLAC Surry, England -// R 1 NAME J. /Smith/ -// +// LR 0 INDI @P3@ +// L 1 NAME John /Smith/ +// LR 1 BIRT +// L 2 DATE Abt. Oct 1943 +// LR 2 DATE 3 SEP 1943 +// R 2 DATE Abt. Sep 1943 +// LR 1 DEAT +// L 2 PLAC England +// R 2 DATE Aft. 2001 +// R 2 PLAC Surry, England +// R 1 NAME J. /Smith/ func CompareNodes(left, right Node) *NodeDiff { result := &NodeDiff{} @@ -218,17 +217,17 @@ func (nd *NodeDiff) string(indent int) string { // String returns a readable comparison of nodes, like: // -// LR 0 INDI @P3@ -// L 1 NAME John /Smith/ -// LR 1 BIRT -// L 2 DATE Abt. Oct 1943 -// LR 2 DATE 3 SEP 1943 -// R 2 DATE Abt. Sep 1943 -// LR 1 DEAT -// L 2 PLAC England -// R 2 DATE Aft. 2001 -// R 2 PLAC Surry, England -// R 1 NAME J. /Smith/ +// LR 0 INDI @P3@ +// L 1 NAME John /Smith/ +// LR 1 BIRT +// L 2 DATE Abt. Oct 1943 +// LR 2 DATE 3 SEP 1943 +// R 2 DATE Abt. Sep 1943 +// LR 1 DEAT +// L 2 PLAC England +// R 2 DATE Aft. 2001 +// R 2 PLAC Surry, England +// R 1 NAME J. /Smith/ // // The L/R/LR represent which side has the node, followed by the GEDCOM indent // and node line. @@ -237,8 +236,8 @@ func (nd *NodeDiff) string(indent int) string { // displayed as two separate lines even though they both belong to the same // NodeDiff: // -// LR 0 INDI @P3@ -// LR 0 INDI @P4@ +// LR 0 INDI @P3@ +// LR 0 INDI @P4@ // // You should not rely on this format to be machine readable as it may change in // the future. @@ -254,16 +253,15 @@ func (nd *NodeDiff) String() string { // The following diff (rendered with String) shows each NodeDiff and if it would // be considered DeepEqual: // -// LR 0 INDI @P3@ | false -// LR 1 NAME John /Smith/ | true -// LR 1 BIRT | false -// L 2 DATE Abt. Oct 1943 | false -// LR 2 DATE 3 SEP 1943 | true -// R 2 DATE Abt. Sep 1943 | false -// LR 1 DEAT | true -// LR 2 PLAC England | true -// R 1 NAME J. /Smith/ | false -// +// LR 0 INDI @P3@ | false +// LR 1 NAME John /Smith/ | true +// LR 1 BIRT | false +// L 2 DATE Abt. Oct 1943 | false +// LR 2 DATE 3 SEP 1943 | true +// R 2 DATE Abt. Sep 1943 | false +// LR 1 DEAT | true +// LR 2 PLAC England | true +// R 1 NAME J. /Smith/ | false func (nd *NodeDiff) IsDeepEqual() bool { leftIsNil := IsNil(nd.Left) rightIsNil := IsNil(nd.Right) @@ -345,7 +343,7 @@ func (nd *NodeDiff) LeftNode() Node { // RightNode returns the flattening Node value that favors the right side. // -// To favor means to return the Left value when both the Left and Right are set. +// To favor means to return the Right value when both the Left and Right are set. func (nd *NodeDiff) RightNode() Node { n := nd.Right diff --git a/simple_node.go b/simple_node.go index 62553c8..fc89328 100644 --- a/simple_node.go +++ b/simple_node.go @@ -61,7 +61,7 @@ func (node *SimpleNode) Identifier() string { if node == nil { return "" } - + return fmt.Sprintf("@%s@", node.pointer) } @@ -84,6 +84,24 @@ func (node *SimpleNode) Equals(node2 Node) bool { } tag := node2.Tag() + //if both Ancestry sources, only check if their _APID is the same + if node.Tag().String() == "Source" && tag.String() == "Source" { + found := false + ancestry: + for _, leftNode := range node.Nodes() { + for _, rightNode := range node2.Nodes() { + leftValue := leftNode.Value() + rightValue := rightNode.Value() + if leftNode.Tag().String() == "_APID" && rightNode.Tag().String() == "_APID" && rightValue == leftValue { + found = true + break ancestry + } + } + } + if found { //can't just return found, because they may be non-ancestry sources + return true + } + } if node.tag != tag { return false }