Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members  

UnitPower.C

00001 #include <citrus/config.h>
00002 #include <stdlib.h>
00003 
00004 #include <glib.h>
00005 
00006 #include <vector>
00007 
00008 #include <citrus/Unit.H>
00009 #include <citrus/Prefix.H>
00010 #include <citrus/UnitPower.H>
00011 
00012 UnitPower::UnitPower()
00013     : m_unit(0), m_prfx(0), m_pwr(0)
00014 {
00015 
00016 }
00017 
00018 UnitPower::UnitPower( Unit* unit, Prefix* prfx, int pwr )
00019     : m_unit(unit), m_prfx( prfx ), m_pwr(pwr)
00020 {
00021 
00022 }
00023 
00024 bool UnitPower::operator ==( const UnitPower& other ) const
00025 {
00026   // Don't compare prefixes.
00027   return ( (m_unit == other.m_unit) && (m_pwr == other.m_pwr) ) ;
00028 }
00029 
00030 UnitPower& UnitPower::operator =( const UnitPower& other )
00031 {
00032   if ( &other == this )
00033     return *this ;
00034 
00035   m_unit = other.m_unit ;
00036   m_prfx = other.m_prfx ;
00037   m_pwr = other.m_pwr ;
00038   return *this ;
00039 }
00040 
00041 bool UnitPower::isNull() const
00042 {
00043   return m_unit == 0 ;
00044 }
00045 
00046 void UnitPower::print( const vector<UnitPower>& upwr, FILE* f )
00047 {
00048   vector<UnitPower>::const_iterator iter = upwr.begin() ;
00049   while ( iter != upwr.end() ) {
00050     if ( iter->m_prfx == 0 )
00051       if ( iter->m_pwr == 1 )
00052         fprintf( f, "(%s)", iter->m_unit->abbr() ) ;
00053       else
00054         fprintf( f, "(%s^%d)", iter->m_unit->abbr(), iter->m_pwr ) ;
00055     else
00056       if ( iter->m_pwr == 1 )
00057         fprintf( f, "(%s%s)", iter->m_prfx->abbr(), iter->m_unit->abbr() ) ;
00058       else
00059         fprintf( f, "(%s%s^%d)", iter->m_prfx->abbr(), iter->m_unit->abbr(),
00060                  iter->m_pwr ) ;
00061     ++iter ;
00062   }
00063 
00064 }
00065 
00066 vector<UnitPower>::iterator find_unit( Unit* unit,
00067                                        vector<UnitPower>& upwr )
00068 {
00069   vector<UnitPower>::iterator iter = upwr.begin() ;
00070   while ( iter != upwr.end() ) {
00071     if ( iter->m_unit == unit )
00072       return iter ;
00073     ++iter ;
00074   }
00075   return upwr.end() ;
00076 }
00077 
00079 xmlNodePtr UnitPower::mathML() const
00080 {
00081   if ( ! m_pwr )
00082     return NULL ;
00083 
00084   xmlNodePtr upn ;
00085   CHAR* content ;
00086 
00087   if ( abs(m_pwr) == 1 ) {
00088     upn = xmlNewNode( NULL, (const CHAR*)"mi" ) ;
00089     content = (CHAR*) g_strdup_printf( "%s%s", m_prfx ? m_prfx->abbr() : "",
00090                                 m_unit->abbr() ) ;
00091     xmlNodeSetContent( upn, content ) ;
00092     g_free( content ) ;
00093   } else {
00094     xmlNodePtr nd ;
00095     upn = xmlNewNode( NULL, (const CHAR*)"msup" ) ;
00096 
00097     content = (CHAR*) g_strdup_printf( "%s%s", m_prfx ? m_prfx->abbr() : "",
00098                                 m_unit->abbr() ) ;
00099     nd = xmlNewChild( upn, NULL, (const CHAR*)"mi", content ) ;
00100     g_free( content ) ;
00101 
00102     content = (CHAR*) g_strdup_printf( "%d", abs(m_pwr) ) ;
00103     nd = xmlNewChild( upn, NULL, (const CHAR*)"mn", content ) ;
00104     g_free( content ) ;
00105   }
00106 
00107   return upn ;
00108 }
00109 
00111 xmlNodePtr UnitPower::mathML( const vector<UnitPower>& upwr )
00112 {
00113   assert( upwr.size() != 0 ) ;
00114   int nnum = 0, nden = 0 ;
00115   xmlNodePtr item ;
00116   xmlNodePtr top = xmlNewNode( NULL, (const CHAR*)"mrow" ) ;
00117   xmlNodePtr frac = xmlNewChild( top, NULL, (const CHAR*)"mfrac", NULL ) ;
00118   xmlNodePtr numer = xmlNewChild( frac, NULL, (const CHAR*)"mrow", NULL ) ;
00119   xmlNodePtr denom = xmlNewChild( frac, NULL, (const CHAR*)"mrow", NULL ) ;
00120 
00121   vector<UnitPower>::const_iterator iter = upwr.begin() ;
00122   while ( iter != upwr.end() ) {
00123     item = iter->mathML() ;
00124     if ( ! item ) 
00125       continue ;
00126 
00127     // Only add the centerdot if this isn't the first item in the
00128     // numerator or denominator.
00129     if ( iter->m_pwr < 0 ) {
00130       if ( nden )
00131         xmlNewChild( denom, NULL,
00132                      (const CHAR*)"mo", (const CHAR*)"&centerdot;" ) ;
00133       xmlAddChild( denom, item ) ;
00134       nden++ ;
00135     } else {
00136       if ( nnum )
00137         xmlNewChild( numer, NULL,
00138                      (const CHAR*)"mo", (const CHAR*)"&centerdot;" ) ;
00139       xmlAddChild( numer, item ) ;
00140       nnum++ ;
00141     }
00142     iter++ ;
00143   }
00144   if ( !nnum ) {
00145     xmlNewChild( numer, NULL, (const CHAR*)"mi", (const CHAR*)"1" ) ;
00146   } else if ( !nden ) {
00147     xmlUnlinkNode( numer ) ;
00148     xmlUnlinkNode( frac ) ;
00149     xmlFreeNode( frac ) ; // also frees denom
00150     xmlAddChild( top, numer ) ;
00151   }
00152   return top ;
00153 }
00154 
Citrus C++ Reference Manual  20010520