Fossil SCM

An attempt to rework HTML unified diff to show partial line matches. Still needs CSS work.

drh 2021-08-31 03:00 diff-color-enhancements
Commit a01e46d85e8788a1109a9efbb0e425ac00606fd9a2445f99d9859ba175efe57c
3 files changed +29 -1 +144 -9 +42 -22
+29 -1
--- src/default.css
+++ src/default.css
@@ -532,11 +532,11 @@
532532
padding-top: 1px;
533533
}
534534
table.sbsdiffcols {
535535
width: 90%;
536536
border-spacing: 0;
537
- font-size: xx-small;
537
+ font-size: small;
538538
}
539539
table.sbsdiffcols td {
540540
padding: 0;
541541
vertical-align: top;
542542
}
@@ -575,10 +575,38 @@
575575
color: #0000ff;
576576
}
577577
span.diffln {
578578
color: #a0a0a0;
579579
}
580
+pre.udiffln {
581
+ color: #a0a0a0;
582
+}
583
+pre.udiffln ins {
584
+ background-color: #a0e4b2;
585
+ text-decoration: none;
586
+}
587
+pre.udiffln del {
588
+ background-color: #ffc0c0;
589
+ text-decoration: none;
590
+}
591
+pre.udifftxt ins {
592
+ background-color: #dafbe1;
593
+ text-decoration: none;
594
+}
595
+pre.udifftxt del {
596
+ background-color: #ffe8e8;
597
+ text-decoration: none;
598
+}
599
+pre.udifftxt ins mark {
600
+ background-color: #a0e4b2;
601
+ text-decoration: none;
602
+}
603
+pre.udifftxt del mark {
604
+ background-color: #ffc0c0;
605
+ text-decoration: none;
606
+}
607
+
580608
span.modpending {
581609
color: #b03800;
582610
font-style: italic;
583611
}
584612
pre.th1result {
585613
--- src/default.css
+++ src/default.css
@@ -532,11 +532,11 @@
532 padding-top: 1px;
533 }
534 table.sbsdiffcols {
535 width: 90%;
536 border-spacing: 0;
537 font-size: xx-small;
538 }
539 table.sbsdiffcols td {
540 padding: 0;
541 vertical-align: top;
542 }
@@ -575,10 +575,38 @@
575 color: #0000ff;
576 }
577 span.diffln {
578 color: #a0a0a0;
579 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
580 span.modpending {
581 color: #b03800;
582 font-style: italic;
583 }
584 pre.th1result {
585
--- src/default.css
+++ src/default.css
@@ -532,11 +532,11 @@
532 padding-top: 1px;
533 }
534 table.sbsdiffcols {
535 width: 90%;
536 border-spacing: 0;
537 font-size: small;
538 }
539 table.sbsdiffcols td {
540 padding: 0;
541 vertical-align: top;
542 }
@@ -575,10 +575,38 @@
575 color: #0000ff;
576 }
577 span.diffln {
578 color: #a0a0a0;
579 }
580 pre.udiffln {
581 color: #a0a0a0;
582 }
583 pre.udiffln ins {
584 background-color: #a0e4b2;
585 text-decoration: none;
586 }
587 pre.udiffln del {
588 background-color: #ffc0c0;
589 text-decoration: none;
590 }
591 pre.udifftxt ins {
592 background-color: #dafbe1;
593 text-decoration: none;
594 }
595 pre.udifftxt del {
596 background-color: #ffe8e8;
597 text-decoration: none;
598 }
599 pre.udifftxt ins mark {
600 background-color: #a0e4b2;
601 text-decoration: none;
602 }
603 pre.udifftxt del mark {
604 background-color: #ffc0c0;
605 text-decoration: none;
606 }
607
608 span.modpending {
609 color: #b03800;
610 font-style: italic;
611 }
612 pre.th1result {
613
+144 -9
--- src/diff.c
+++ src/diff.c
@@ -1627,25 +1627,27 @@
16271627
** lines and formats them for display. Subclasses of this object format
16281628
** the diff output in different ways.
16291629
*/
16301630
typedef struct DiffBuilder DiffBuilder;
16311631
struct DiffBuilder {
1632
- void (*xSkip)(DiffBuilder*, unsigned int);
1632
+ void (*xSkip)(DiffBuilder*, unsigned int, int);
16331633
void (*xCommon)(DiffBuilder*,const DLine*);
16341634
void (*xInsert)(DiffBuilder*,const DLine*);
16351635
void (*xDelete)(DiffBuilder*,const DLine*);
16361636
void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
16371637
void (*xEnd)(DiffBuilder*);
16381638
unsigned int lnLeft; /* Lines seen on the left (delete) side */
16391639
unsigned int lnRight; /* Lines seen on the right (insert) side */
16401640
Blob *pOut; /* Output blob */
1641
+ Blob aCol[5]; /* Holding blobs */
16411642
};
16421643
16431644
/************************* DiffBuilderDebug ********************************/
1644
-static void dfdebugSkip(DiffBuilder *p, unsigned int n){
1645
- blob_appendf(p->pOut, "SKIP %d (%d..%d left and %d..%d right)\n",
1646
- n, p->lnLeft+1, p->lnLeft+n, p->lnRight+1, p->lnRight+n);
1645
+static void dfdebugSkip(DiffBuilder *p, unsigned int n, int isFinal){
1646
+ blob_appendf(p->pOut, "SKIP %d (%d..%d left and %d..%d right)%s\n",
1647
+ n, p->lnLeft+1, p->lnLeft+n, p->lnRight+1, p->lnRight+n,
1648
+ isFinal ? " FINAL" : "");
16471649
p->lnLeft += n;
16481650
p->lnRight += n;
16491651
}
16501652
static void dfdebugCommon(DiffBuilder *p, const DLine *pLine){
16511653
p->lnLeft++;
@@ -1782,11 +1784,11 @@
17821784
break;
17831785
}
17841786
}
17851787
*piCol = iCol;
17861788
}
1787
-static void dfjsonSkip(DiffBuilder *p, unsigned int n){
1789
+static void dfjsonSkip(DiffBuilder *p, unsigned int n, int isFinal){
17881790
blob_appendf(p->pOut, "1,%u,\n", n);
17891791
}
17901792
static void dfjsonCommon(DiffBuilder *p, const DLine *pLine){
17911793
int iCol = 0;
17921794
blob_append(p->pOut, "2,\"",3);
@@ -1815,11 +1817,11 @@
18151817
for(i=x=iCol=0; i<span.n; i++){
18161818
int ofst = span.a[i].iStart1;
18171819
int len = span.a[i].iLen1;
18181820
if( len ){
18191821
jsonize_to_blob(p->pOut, pX->z+x, ofst - x, &iCol);
1820
- x += ofst;
1822
+ x = ofst;
18211823
blob_append(p->pOut, "<mark>", 6);
18221824
jsonize_to_blob(p->pOut, pX->z+x, len, &iCol);
18231825
x += len;
18241826
blob_append(p->pOut, "</mark>", 7);
18251827
}
@@ -1829,11 +1831,11 @@
18291831
for(i=x=iCol=0; i<span.n; i++){
18301832
int ofst = span.a[i].iStart2;
18311833
int len = span.a[i].iLen2;
18321834
if( len ){
18331835
jsonize_to_blob(p->pOut, pY->z+x, ofst - x, &iCol);
1834
- x += ofst;
1836
+ x = ofst;
18351837
blob_append(p->pOut, "<mark>", 6);
18361838
jsonize_to_blob(p->pOut, pY->z+x, len, &iCol);
18371839
x += len;
18381840
blob_append(p->pOut, "</mark>", 7);
18391841
}
@@ -1856,10 +1858,140 @@
18561858
p->lnLeft = p->lnRight = 0;
18571859
p->pOut = pOut;
18581860
blob_append_char(pOut, '[');
18591861
return p;
18601862
}
1863
+
1864
+/************************* DiffBuilderUnified********************************/
1865
+
1866
+/* Accumulator strategy:
1867
+**
1868
+** * Common and Delete line numbers are output directly to p->pOut
1869
+** * Common and Delete text accumulates in p->aCol[0].
1870
+** * Pending insert lines numbers go into p->aCol[1].
1871
+** * Pending insert text goes into p->aCol[2].
1872
+*/
1873
+static void dfunifiedEmitInsert(DiffBuilder *p){
1874
+ if( blob_size(&p->aCol[1])==0 ) return;
1875
+ blob_append(p->pOut, blob_buffer(&p->aCol[1]), blob_size(&p->aCol[1]));
1876
+ blob_reset(&p->aCol[1]);
1877
+ blob_append(&p->aCol[0], blob_buffer(&p->aCol[2]), blob_size(&p->aCol[2]));
1878
+ blob_reset(&p->aCol[2]);
1879
+}
1880
+static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){
1881
+ dfunifiedEmitInsert(p);
1882
+ if( (p->lnLeft || p->lnRight) && !isFinal ){
1883
+ blob_append(p->pOut,
1884
+ "<span class=\"diffhr\">"
1885
+ ".................."
1886
+ "</span>\n",
1887
+ -1);
1888
+ blob_append(&p->aCol[0],
1889
+ "<span class=\"diffhr\">"
1890
+ "..............................................................."
1891
+ "</span>\n",
1892
+ -1);
1893
+ }
1894
+ p->lnLeft += n;
1895
+ p->lnRight += n;
1896
+}
1897
+static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
1898
+ int iCol = 0;
1899
+ dfunifiedEmitInsert(p);
1900
+ p->lnLeft++;
1901
+ p->lnRight++;
1902
+ blob_appendf(p->pOut,"%6d %6d\n", p->lnLeft, p->lnRight);
1903
+ jsonize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n, &iCol);
1904
+ blob_append_char(&p->aCol[0], '\n');
1905
+}
1906
+static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){
1907
+ int iCol = 0;
1908
+ p->lnRight++;
1909
+ blob_appendf(&p->aCol[1]," <ins>%6d</ins>\n", p->lnRight);
1910
+ blob_append(&p->aCol[2],"<ins>",-1);
1911
+ jsonize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n, &iCol);
1912
+ blob_append(&p->aCol[2], "</ins>\n", -1);
1913
+}
1914
+static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){
1915
+ int iCol = 0;
1916
+ p->lnLeft++;
1917
+ blob_appendf(p->pOut,"<del>%6d</del> \n", p->lnLeft);
1918
+ blob_append(&p->aCol[0],"<del>",-1);
1919
+ jsonize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n, &iCol);
1920
+ blob_append(&p->aCol[0], "</del>\n", -1);
1921
+}
1922
+static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1923
+ int i;
1924
+ int x;
1925
+ int iCol;
1926
+ ChangeSpan span;
1927
+ oneLineChange(pX, pY, &span);
1928
+ p->lnLeft++;
1929
+ p->lnRight++;
1930
+ blob_appendf(p->pOut,"<del>%6d</del> \n", p->lnLeft);
1931
+ blob_append(&p->aCol[0], "<del>", -1);
1932
+ for(i=x=iCol=0; i<span.n; i++){
1933
+ int ofst = span.a[i].iStart1;
1934
+ int len = span.a[i].iLen1;
1935
+ if( len ){
1936
+ jsonize_to_blob(&p->aCol[0], pX->z+x, ofst - x, &iCol);
1937
+ x = ofst;
1938
+ blob_append(&p->aCol[0], "<mark>", 6);
1939
+ jsonize_to_blob(&p->aCol[0], pX->z+x, len, &iCol);
1940
+ x += len;
1941
+ blob_append(&p->aCol[0], "</mark>", 7);
1942
+ }
1943
+ }
1944
+ if( x<pX->n ) jsonize_to_blob(&p->aCol[0], pX->z+x, pX->n - x, &iCol);
1945
+ blob_append(&p->aCol[0], "</del>\n", -1);
1946
+ blob_appendf(&p->aCol[1]," <ins>%6d</ins>\n", p->lnRight);
1947
+ blob_append(&p->aCol[2], "<ins>", -1);
1948
+ for(i=x=iCol=0; i<span.n; i++){
1949
+ int ofst = span.a[i].iStart2;
1950
+ int len = span.a[i].iLen2;
1951
+ if( len ){
1952
+ jsonize_to_blob(&p->aCol[2], pY->z+x, ofst - x, &iCol);
1953
+ x = ofst;
1954
+ blob_append(&p->aCol[2], "<mark>", 6);
1955
+ jsonize_to_blob(&p->aCol[2], pY->z+x, len, &iCol);
1956
+ x += len;
1957
+ blob_append(&p->aCol[2], "</mark>", 7);
1958
+ }
1959
+ }
1960
+ if( x<pY->n ) jsonize_to_blob(&p->aCol[2], pY->z+x, pY->n - x, &iCol);
1961
+ blob_append(&p->aCol[2], "</ins>\n", -1);
1962
+}
1963
+static void dfunifiedEnd(DiffBuilder *p){
1964
+ dfunifiedEmitInsert(p);
1965
+ blob_append(p->pOut,
1966
+ "</pre></td>\n"
1967
+ "<td class=\"udifftxt\" width=\"100%\"><pre class=\"udifftxt\">\n",
1968
+ -1);
1969
+ blob_append(p->pOut, blob_buffer(&p->aCol[0]), blob_size(&p->aCol[0]));
1970
+ blob_reset(&p->aCol[0]);
1971
+ blob_append(p->pOut, "</pre></td></tr>\n</table>\n", -1);
1972
+ fossil_free(p);
1973
+}
1974
+static DiffBuilder *dfunifiedNew(Blob *pOut){
1975
+ DiffBuilder *p = fossil_malloc(sizeof(*p));
1976
+ p->xSkip = dfunifiedSkip;
1977
+ p->xCommon = dfunifiedCommon;
1978
+ p->xInsert = dfunifiedInsert;
1979
+ p->xDelete = dfunifiedDelete;
1980
+ p->xEdit = dfunifiedEdit;
1981
+ p->xEnd = dfunifiedEnd;
1982
+ p->lnLeft = p->lnRight = 0;
1983
+ p->pOut = pOut;
1984
+ blob_append(pOut,
1985
+ "<table class=\"sbsdiffcols\">\n"
1986
+ "<tr><td class=\"udiffln\"><pre class=\"udiffln\">\n",
1987
+ -1);
1988
+ blob_init(&p->aCol[0], 0, 0);
1989
+ blob_init(&p->aCol[1], 0, 0);
1990
+ blob_init(&p->aCol[2], 0, 0);
1991
+ return p;
1992
+}
18611993
/****************************************************************************/
18621994
18631995
/*
18641996
** Format a diff using a DiffBuilder object
18651997
*/
@@ -1949,11 +2081,11 @@
19492081
a += skip;
19502082
b += skip;
19512083
m = R[r] - skip;
19522084
if( r ) skip -= nContext;
19532085
if( skip>0 ){
1954
- pBuilder->xSkip(pBuilder, skip);
2086
+ pBuilder->xSkip(pBuilder, skip, 0);
19552087
}
19562088
for(j=0; j<m; j++){
19572089
pBuilder->xCommon(pBuilder, &A[a+j]);
19582090
}
19592091
a += m;
@@ -2024,11 +2156,11 @@
20242156
for(j=0; j<m && j<nContext; j++){
20252157
pBuilder->xCommon(pBuilder, &A[a+j]);
20262158
}
20272159
}
20282160
if( R[r]>nContext ){
2029
- pBuilder->xSkip(pBuilder, R[r] - nContext);
2161
+ pBuilder->xSkip(pBuilder, R[r] - nContext, 1);
20302162
}
20312163
pBuilder->xEnd(pBuilder);
20322164
}
20332165
20342166
@@ -2587,10 +2719,13 @@
25872719
}else if( diffFlags & DIFF_SIDEBYSIDE ){
25882720
sbsDiff(&c, pOut, pRe, diffFlags);
25892721
}else if( diffFlags & DIFF_DEBUG ){
25902722
DiffBuilder *pBuilder = dfdebugNew(pOut);
25912723
formatDiff(&c, pRe, diffFlags, pBuilder);
2724
+ }else if( diffFlags & DIFF_HTML ){
2725
+ DiffBuilder *pBuilder = dfunifiedNew(pOut);
2726
+ formatDiff(&c, pRe, diffFlags, pBuilder);
25922727
}else{
25932728
contextDiff(&c, pOut, pRe, diffFlags);
25942729
}
25952730
fossil_free(c.aFrom);
25962731
fossil_free(c.aTo);
25972732
--- src/diff.c
+++ src/diff.c
@@ -1627,25 +1627,27 @@
1627 ** lines and formats them for display. Subclasses of this object format
1628 ** the diff output in different ways.
1629 */
1630 typedef struct DiffBuilder DiffBuilder;
1631 struct DiffBuilder {
1632 void (*xSkip)(DiffBuilder*, unsigned int);
1633 void (*xCommon)(DiffBuilder*,const DLine*);
1634 void (*xInsert)(DiffBuilder*,const DLine*);
1635 void (*xDelete)(DiffBuilder*,const DLine*);
1636 void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
1637 void (*xEnd)(DiffBuilder*);
1638 unsigned int lnLeft; /* Lines seen on the left (delete) side */
1639 unsigned int lnRight; /* Lines seen on the right (insert) side */
1640 Blob *pOut; /* Output blob */
 
1641 };
1642
1643 /************************* DiffBuilderDebug ********************************/
1644 static void dfdebugSkip(DiffBuilder *p, unsigned int n){
1645 blob_appendf(p->pOut, "SKIP %d (%d..%d left and %d..%d right)\n",
1646 n, p->lnLeft+1, p->lnLeft+n, p->lnRight+1, p->lnRight+n);
 
1647 p->lnLeft += n;
1648 p->lnRight += n;
1649 }
1650 static void dfdebugCommon(DiffBuilder *p, const DLine *pLine){
1651 p->lnLeft++;
@@ -1782,11 +1784,11 @@
1782 break;
1783 }
1784 }
1785 *piCol = iCol;
1786 }
1787 static void dfjsonSkip(DiffBuilder *p, unsigned int n){
1788 blob_appendf(p->pOut, "1,%u,\n", n);
1789 }
1790 static void dfjsonCommon(DiffBuilder *p, const DLine *pLine){
1791 int iCol = 0;
1792 blob_append(p->pOut, "2,\"",3);
@@ -1815,11 +1817,11 @@
1815 for(i=x=iCol=0; i<span.n; i++){
1816 int ofst = span.a[i].iStart1;
1817 int len = span.a[i].iLen1;
1818 if( len ){
1819 jsonize_to_blob(p->pOut, pX->z+x, ofst - x, &iCol);
1820 x += ofst;
1821 blob_append(p->pOut, "<mark>", 6);
1822 jsonize_to_blob(p->pOut, pX->z+x, len, &iCol);
1823 x += len;
1824 blob_append(p->pOut, "</mark>", 7);
1825 }
@@ -1829,11 +1831,11 @@
1829 for(i=x=iCol=0; i<span.n; i++){
1830 int ofst = span.a[i].iStart2;
1831 int len = span.a[i].iLen2;
1832 if( len ){
1833 jsonize_to_blob(p->pOut, pY->z+x, ofst - x, &iCol);
1834 x += ofst;
1835 blob_append(p->pOut, "<mark>", 6);
1836 jsonize_to_blob(p->pOut, pY->z+x, len, &iCol);
1837 x += len;
1838 blob_append(p->pOut, "</mark>", 7);
1839 }
@@ -1856,10 +1858,140 @@
1856 p->lnLeft = p->lnRight = 0;
1857 p->pOut = pOut;
1858 blob_append_char(pOut, '[');
1859 return p;
1860 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1861 /****************************************************************************/
1862
1863 /*
1864 ** Format a diff using a DiffBuilder object
1865 */
@@ -1949,11 +2081,11 @@
1949 a += skip;
1950 b += skip;
1951 m = R[r] - skip;
1952 if( r ) skip -= nContext;
1953 if( skip>0 ){
1954 pBuilder->xSkip(pBuilder, skip);
1955 }
1956 for(j=0; j<m; j++){
1957 pBuilder->xCommon(pBuilder, &A[a+j]);
1958 }
1959 a += m;
@@ -2024,11 +2156,11 @@
2024 for(j=0; j<m && j<nContext; j++){
2025 pBuilder->xCommon(pBuilder, &A[a+j]);
2026 }
2027 }
2028 if( R[r]>nContext ){
2029 pBuilder->xSkip(pBuilder, R[r] - nContext);
2030 }
2031 pBuilder->xEnd(pBuilder);
2032 }
2033
2034
@@ -2587,10 +2719,13 @@
2587 }else if( diffFlags & DIFF_SIDEBYSIDE ){
2588 sbsDiff(&c, pOut, pRe, diffFlags);
2589 }else if( diffFlags & DIFF_DEBUG ){
2590 DiffBuilder *pBuilder = dfdebugNew(pOut);
2591 formatDiff(&c, pRe, diffFlags, pBuilder);
 
 
 
2592 }else{
2593 contextDiff(&c, pOut, pRe, diffFlags);
2594 }
2595 fossil_free(c.aFrom);
2596 fossil_free(c.aTo);
2597
--- src/diff.c
+++ src/diff.c
@@ -1627,25 +1627,27 @@
1627 ** lines and formats them for display. Subclasses of this object format
1628 ** the diff output in different ways.
1629 */
1630 typedef struct DiffBuilder DiffBuilder;
1631 struct DiffBuilder {
1632 void (*xSkip)(DiffBuilder*, unsigned int, int);
1633 void (*xCommon)(DiffBuilder*,const DLine*);
1634 void (*xInsert)(DiffBuilder*,const DLine*);
1635 void (*xDelete)(DiffBuilder*,const DLine*);
1636 void (*xEdit)(DiffBuilder*,const DLine*,const DLine*);
1637 void (*xEnd)(DiffBuilder*);
1638 unsigned int lnLeft; /* Lines seen on the left (delete) side */
1639 unsigned int lnRight; /* Lines seen on the right (insert) side */
1640 Blob *pOut; /* Output blob */
1641 Blob aCol[5]; /* Holding blobs */
1642 };
1643
1644 /************************* DiffBuilderDebug ********************************/
1645 static void dfdebugSkip(DiffBuilder *p, unsigned int n, int isFinal){
1646 blob_appendf(p->pOut, "SKIP %d (%d..%d left and %d..%d right)%s\n",
1647 n, p->lnLeft+1, p->lnLeft+n, p->lnRight+1, p->lnRight+n,
1648 isFinal ? " FINAL" : "");
1649 p->lnLeft += n;
1650 p->lnRight += n;
1651 }
1652 static void dfdebugCommon(DiffBuilder *p, const DLine *pLine){
1653 p->lnLeft++;
@@ -1782,11 +1784,11 @@
1784 break;
1785 }
1786 }
1787 *piCol = iCol;
1788 }
1789 static void dfjsonSkip(DiffBuilder *p, unsigned int n, int isFinal){
1790 blob_appendf(p->pOut, "1,%u,\n", n);
1791 }
1792 static void dfjsonCommon(DiffBuilder *p, const DLine *pLine){
1793 int iCol = 0;
1794 blob_append(p->pOut, "2,\"",3);
@@ -1815,11 +1817,11 @@
1817 for(i=x=iCol=0; i<span.n; i++){
1818 int ofst = span.a[i].iStart1;
1819 int len = span.a[i].iLen1;
1820 if( len ){
1821 jsonize_to_blob(p->pOut, pX->z+x, ofst - x, &iCol);
1822 x = ofst;
1823 blob_append(p->pOut, "<mark>", 6);
1824 jsonize_to_blob(p->pOut, pX->z+x, len, &iCol);
1825 x += len;
1826 blob_append(p->pOut, "</mark>", 7);
1827 }
@@ -1829,11 +1831,11 @@
1831 for(i=x=iCol=0; i<span.n; i++){
1832 int ofst = span.a[i].iStart2;
1833 int len = span.a[i].iLen2;
1834 if( len ){
1835 jsonize_to_blob(p->pOut, pY->z+x, ofst - x, &iCol);
1836 x = ofst;
1837 blob_append(p->pOut, "<mark>", 6);
1838 jsonize_to_blob(p->pOut, pY->z+x, len, &iCol);
1839 x += len;
1840 blob_append(p->pOut, "</mark>", 7);
1841 }
@@ -1856,10 +1858,140 @@
1858 p->lnLeft = p->lnRight = 0;
1859 p->pOut = pOut;
1860 blob_append_char(pOut, '[');
1861 return p;
1862 }
1863
1864 /************************* DiffBuilderUnified********************************/
1865
1866 /* Accumulator strategy:
1867 **
1868 ** * Common and Delete line numbers are output directly to p->pOut
1869 ** * Common and Delete text accumulates in p->aCol[0].
1870 ** * Pending insert lines numbers go into p->aCol[1].
1871 ** * Pending insert text goes into p->aCol[2].
1872 */
1873 static void dfunifiedEmitInsert(DiffBuilder *p){
1874 if( blob_size(&p->aCol[1])==0 ) return;
1875 blob_append(p->pOut, blob_buffer(&p->aCol[1]), blob_size(&p->aCol[1]));
1876 blob_reset(&p->aCol[1]);
1877 blob_append(&p->aCol[0], blob_buffer(&p->aCol[2]), blob_size(&p->aCol[2]));
1878 blob_reset(&p->aCol[2]);
1879 }
1880 static void dfunifiedSkip(DiffBuilder *p, unsigned int n, int isFinal){
1881 dfunifiedEmitInsert(p);
1882 if( (p->lnLeft || p->lnRight) && !isFinal ){
1883 blob_append(p->pOut,
1884 "<span class=\"diffhr\">"
1885 ".................."
1886 "</span>\n",
1887 -1);
1888 blob_append(&p->aCol[0],
1889 "<span class=\"diffhr\">"
1890 "..............................................................."
1891 "</span>\n",
1892 -1);
1893 }
1894 p->lnLeft += n;
1895 p->lnRight += n;
1896 }
1897 static void dfunifiedCommon(DiffBuilder *p, const DLine *pLine){
1898 int iCol = 0;
1899 dfunifiedEmitInsert(p);
1900 p->lnLeft++;
1901 p->lnRight++;
1902 blob_appendf(p->pOut,"%6d %6d\n", p->lnLeft, p->lnRight);
1903 jsonize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n, &iCol);
1904 blob_append_char(&p->aCol[0], '\n');
1905 }
1906 static void dfunifiedInsert(DiffBuilder *p, const DLine *pLine){
1907 int iCol = 0;
1908 p->lnRight++;
1909 blob_appendf(&p->aCol[1]," <ins>%6d</ins>\n", p->lnRight);
1910 blob_append(&p->aCol[2],"<ins>",-1);
1911 jsonize_to_blob(&p->aCol[2], pLine->z, (int)pLine->n, &iCol);
1912 blob_append(&p->aCol[2], "</ins>\n", -1);
1913 }
1914 static void dfunifiedDelete(DiffBuilder *p, const DLine *pLine){
1915 int iCol = 0;
1916 p->lnLeft++;
1917 blob_appendf(p->pOut,"<del>%6d</del> \n", p->lnLeft);
1918 blob_append(&p->aCol[0],"<del>",-1);
1919 jsonize_to_blob(&p->aCol[0], pLine->z, (int)pLine->n, &iCol);
1920 blob_append(&p->aCol[0], "</del>\n", -1);
1921 }
1922 static void dfunifiedEdit(DiffBuilder *p, const DLine *pX, const DLine *pY){
1923 int i;
1924 int x;
1925 int iCol;
1926 ChangeSpan span;
1927 oneLineChange(pX, pY, &span);
1928 p->lnLeft++;
1929 p->lnRight++;
1930 blob_appendf(p->pOut,"<del>%6d</del> \n", p->lnLeft);
1931 blob_append(&p->aCol[0], "<del>", -1);
1932 for(i=x=iCol=0; i<span.n; i++){
1933 int ofst = span.a[i].iStart1;
1934 int len = span.a[i].iLen1;
1935 if( len ){
1936 jsonize_to_blob(&p->aCol[0], pX->z+x, ofst - x, &iCol);
1937 x = ofst;
1938 blob_append(&p->aCol[0], "<mark>", 6);
1939 jsonize_to_blob(&p->aCol[0], pX->z+x, len, &iCol);
1940 x += len;
1941 blob_append(&p->aCol[0], "</mark>", 7);
1942 }
1943 }
1944 if( x<pX->n ) jsonize_to_blob(&p->aCol[0], pX->z+x, pX->n - x, &iCol);
1945 blob_append(&p->aCol[0], "</del>\n", -1);
1946 blob_appendf(&p->aCol[1]," <ins>%6d</ins>\n", p->lnRight);
1947 blob_append(&p->aCol[2], "<ins>", -1);
1948 for(i=x=iCol=0; i<span.n; i++){
1949 int ofst = span.a[i].iStart2;
1950 int len = span.a[i].iLen2;
1951 if( len ){
1952 jsonize_to_blob(&p->aCol[2], pY->z+x, ofst - x, &iCol);
1953 x = ofst;
1954 blob_append(&p->aCol[2], "<mark>", 6);
1955 jsonize_to_blob(&p->aCol[2], pY->z+x, len, &iCol);
1956 x += len;
1957 blob_append(&p->aCol[2], "</mark>", 7);
1958 }
1959 }
1960 if( x<pY->n ) jsonize_to_blob(&p->aCol[2], pY->z+x, pY->n - x, &iCol);
1961 blob_append(&p->aCol[2], "</ins>\n", -1);
1962 }
1963 static void dfunifiedEnd(DiffBuilder *p){
1964 dfunifiedEmitInsert(p);
1965 blob_append(p->pOut,
1966 "</pre></td>\n"
1967 "<td class=\"udifftxt\" width=\"100%\"><pre class=\"udifftxt\">\n",
1968 -1);
1969 blob_append(p->pOut, blob_buffer(&p->aCol[0]), blob_size(&p->aCol[0]));
1970 blob_reset(&p->aCol[0]);
1971 blob_append(p->pOut, "</pre></td></tr>\n</table>\n", -1);
1972 fossil_free(p);
1973 }
1974 static DiffBuilder *dfunifiedNew(Blob *pOut){
1975 DiffBuilder *p = fossil_malloc(sizeof(*p));
1976 p->xSkip = dfunifiedSkip;
1977 p->xCommon = dfunifiedCommon;
1978 p->xInsert = dfunifiedInsert;
1979 p->xDelete = dfunifiedDelete;
1980 p->xEdit = dfunifiedEdit;
1981 p->xEnd = dfunifiedEnd;
1982 p->lnLeft = p->lnRight = 0;
1983 p->pOut = pOut;
1984 blob_append(pOut,
1985 "<table class=\"sbsdiffcols\">\n"
1986 "<tr><td class=\"udiffln\"><pre class=\"udiffln\">\n",
1987 -1);
1988 blob_init(&p->aCol[0], 0, 0);
1989 blob_init(&p->aCol[1], 0, 0);
1990 blob_init(&p->aCol[2], 0, 0);
1991 return p;
1992 }
1993 /****************************************************************************/
1994
1995 /*
1996 ** Format a diff using a DiffBuilder object
1997 */
@@ -1949,11 +2081,11 @@
2081 a += skip;
2082 b += skip;
2083 m = R[r] - skip;
2084 if( r ) skip -= nContext;
2085 if( skip>0 ){
2086 pBuilder->xSkip(pBuilder, skip, 0);
2087 }
2088 for(j=0; j<m; j++){
2089 pBuilder->xCommon(pBuilder, &A[a+j]);
2090 }
2091 a += m;
@@ -2024,11 +2156,11 @@
2156 for(j=0; j<m && j<nContext; j++){
2157 pBuilder->xCommon(pBuilder, &A[a+j]);
2158 }
2159 }
2160 if( R[r]>nContext ){
2161 pBuilder->xSkip(pBuilder, R[r] - nContext, 1);
2162 }
2163 pBuilder->xEnd(pBuilder);
2164 }
2165
2166
@@ -2587,10 +2719,13 @@
2719 }else if( diffFlags & DIFF_SIDEBYSIDE ){
2720 sbsDiff(&c, pOut, pRe, diffFlags);
2721 }else if( diffFlags & DIFF_DEBUG ){
2722 DiffBuilder *pBuilder = dfdebugNew(pOut);
2723 formatDiff(&c, pRe, diffFlags, pBuilder);
2724 }else if( diffFlags & DIFF_HTML ){
2725 DiffBuilder *pBuilder = dfunifiedNew(pOut);
2726 formatDiff(&c, pRe, diffFlags, pBuilder);
2727 }else{
2728 contextDiff(&c, pOut, pRe, diffFlags);
2729 }
2730 fossil_free(c.aFrom);
2731 fossil_free(c.aTo);
2732
+42 -22
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -174,17 +174,23 @@
174174
}else{
175175
blob_appendf(diffBlob, "%s", z);
176176
}
177177
fossil_free(z);
178178
}
179
+
179180
180181
/*
181
-** Extra CSS for side-by-side diffs
182
+** Default header text for diff with --webpage
182183
*/
183
-static const char zSbsCss[] =
184
+static const char zWebpageHdr[] =
185
+@ <!DOCTYPE html>
186
+@ <html>
187
+@ <head>
188
+@ <meta charset="UTF-8">
189
+@ <style>
184190
@ table.sbsdiffcols {
185
-@ width: 90%;
191
+@ width: 90%%;
186192
@ border-spacing: 0;
187193
@ font-size: small;
188194
@ }
189195
@ table.sbsdiffcols td {
190196
@ padding: 0;
@@ -205,22 +211,11 @@
205211
@ overflow-x: auto;
206212
@ }
207213
@ div.diffmkrcol {
208214
@ padding: 0 1em;
209215
@ }
210
-;
211
-
212
-/*
213
-** Default header text for diff with --webpage
214
-*/
215
-static const char zWebpageHdr[] =
216
-@ <!DOCTYPE html>
217
-@ <html>
218
-@ <head>
219
-@ <meta charset="UTF-8">
220
-@ <style>
221
-@ %sspan.diffchng {
216
+@ span.diffchng {
222217
@ background-color: #c0c0ff;
223218
@ }
224219
@ span.diffadd {
225220
@ background-color: #c0ffc0;
226221
@ }
@@ -233,10 +228,41 @@
233228
@ color: #0000ff;
234229
@ }
235230
@ span.diffln {
236231
@ color: #a0a0a0;
237232
@ }
233
+@ table.udiff {
234
+@ width: 90%%;
235
+@ border-spacing: 0;
236
+@ }
237
+@ pre.udiffln {
238
+@ color: #a0a0a0;
239
+@ }
240
+@ pre.udiffln ins {
241
+@ background-color: #a0e4b2;
242
+@ text-decoration: none;
243
+@ }
244
+@ pre.udiffln del {
245
+@ background-color: #ffc0c0;
246
+@ text-decoration: none;
247
+@ }
248
+@ pre.udifftxt ins {
249
+@ background-color: #dafbe1;
250
+@ text-decoration: none;
251
+@ }
252
+@ pre.udifftxt del {
253
+@ background-color: #ffe8e8;
254
+@ text-decoration: none;
255
+@ }
256
+@ pre.udifftxt ins mark {
257
+@ background-color: #a0e4b2;
258
+@ text-decoration: none;
259
+@ }
260
+@ pre.udifftxt del mark {
261
+@ background-color: #ffc0c0;
262
+@ text-decoration: none;
263
+@ }
238264
@ h1 {
239265
@ font-size: 150%%;
240266
@ }
241267
@ </style>
242268
@ </head>
@@ -301,17 +327,11 @@
301327
#else
302328
SetConsoleCtrlHandler(diff_console_ctrl_handler, TRUE);
303329
#endif
304330
}
305331
if( (diffFlags & DIFF_WEBPAGE)!=0 ){
306
- const char *zExtra;
307
- if( diffFlags & DIFF_SIDEBYSIDE ){
308
- zExtra = zSbsCss;
309
- }else{
310
- zExtra = "";
311
- }
312
- fossil_print(zWebpageHdr/*works-like:"%s"*/, zExtra);
332
+ fossil_print(zWebpageHdr/*works-like:""*/);
313333
fflush(stdout);
314334
}
315335
}
316336
317337
/* Do any final output required by a diff and complete the diff
318338
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -174,17 +174,23 @@
174 }else{
175 blob_appendf(diffBlob, "%s", z);
176 }
177 fossil_free(z);
178 }
 
179
180 /*
181 ** Extra CSS for side-by-side diffs
182 */
183 static const char zSbsCss[] =
 
 
 
 
 
184 @ table.sbsdiffcols {
185 @ width: 90%;
186 @ border-spacing: 0;
187 @ font-size: small;
188 @ }
189 @ table.sbsdiffcols td {
190 @ padding: 0;
@@ -205,22 +211,11 @@
205 @ overflow-x: auto;
206 @ }
207 @ div.diffmkrcol {
208 @ padding: 0 1em;
209 @ }
210 ;
211
212 /*
213 ** Default header text for diff with --webpage
214 */
215 static const char zWebpageHdr[] =
216 @ <!DOCTYPE html>
217 @ <html>
218 @ <head>
219 @ <meta charset="UTF-8">
220 @ <style>
221 @ %sspan.diffchng {
222 @ background-color: #c0c0ff;
223 @ }
224 @ span.diffadd {
225 @ background-color: #c0ffc0;
226 @ }
@@ -233,10 +228,41 @@
233 @ color: #0000ff;
234 @ }
235 @ span.diffln {
236 @ color: #a0a0a0;
237 @ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238 @ h1 {
239 @ font-size: 150%%;
240 @ }
241 @ </style>
242 @ </head>
@@ -301,17 +327,11 @@
301 #else
302 SetConsoleCtrlHandler(diff_console_ctrl_handler, TRUE);
303 #endif
304 }
305 if( (diffFlags & DIFF_WEBPAGE)!=0 ){
306 const char *zExtra;
307 if( diffFlags & DIFF_SIDEBYSIDE ){
308 zExtra = zSbsCss;
309 }else{
310 zExtra = "";
311 }
312 fossil_print(zWebpageHdr/*works-like:"%s"*/, zExtra);
313 fflush(stdout);
314 }
315 }
316
317 /* Do any final output required by a diff and complete the diff
318
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -174,17 +174,23 @@
174 }else{
175 blob_appendf(diffBlob, "%s", z);
176 }
177 fossil_free(z);
178 }
179
180
181 /*
182 ** Default header text for diff with --webpage
183 */
184 static const char zWebpageHdr[] =
185 @ <!DOCTYPE html>
186 @ <html>
187 @ <head>
188 @ <meta charset="UTF-8">
189 @ <style>
190 @ table.sbsdiffcols {
191 @ width: 90%%;
192 @ border-spacing: 0;
193 @ font-size: small;
194 @ }
195 @ table.sbsdiffcols td {
196 @ padding: 0;
@@ -205,22 +211,11 @@
211 @ overflow-x: auto;
212 @ }
213 @ div.diffmkrcol {
214 @ padding: 0 1em;
215 @ }
216 @ span.diffchng {
 
 
 
 
 
 
 
 
 
 
 
217 @ background-color: #c0c0ff;
218 @ }
219 @ span.diffadd {
220 @ background-color: #c0ffc0;
221 @ }
@@ -233,10 +228,41 @@
228 @ color: #0000ff;
229 @ }
230 @ span.diffln {
231 @ color: #a0a0a0;
232 @ }
233 @ table.udiff {
234 @ width: 90%%;
235 @ border-spacing: 0;
236 @ }
237 @ pre.udiffln {
238 @ color: #a0a0a0;
239 @ }
240 @ pre.udiffln ins {
241 @ background-color: #a0e4b2;
242 @ text-decoration: none;
243 @ }
244 @ pre.udiffln del {
245 @ background-color: #ffc0c0;
246 @ text-decoration: none;
247 @ }
248 @ pre.udifftxt ins {
249 @ background-color: #dafbe1;
250 @ text-decoration: none;
251 @ }
252 @ pre.udifftxt del {
253 @ background-color: #ffe8e8;
254 @ text-decoration: none;
255 @ }
256 @ pre.udifftxt ins mark {
257 @ background-color: #a0e4b2;
258 @ text-decoration: none;
259 @ }
260 @ pre.udifftxt del mark {
261 @ background-color: #ffc0c0;
262 @ text-decoration: none;
263 @ }
264 @ h1 {
265 @ font-size: 150%%;
266 @ }
267 @ </style>
268 @ </head>
@@ -301,17 +327,11 @@
327 #else
328 SetConsoleCtrlHandler(diff_console_ctrl_handler, TRUE);
329 #endif
330 }
331 if( (diffFlags & DIFF_WEBPAGE)!=0 ){
332 fossil_print(zWebpageHdr/*works-like:""*/);
 
 
 
 
 
 
333 fflush(stdout);
334 }
335 }
336
337 /* Do any final output required by a diff and complete the diff
338

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button