How I can paint a text background with spdlog? - c++

I did a test with the {fmt} and was super easy to change background color, but I can't get the same with spdlog.
I can get the same result with spdlog, but is a weird code
fmt::print( bg( fmt::terminal_color::yellow ) | fg( fmt::terminal_color::black ), " {1:<{0}}\n", 120, "message" );
spdlog::set_pattern( "%v" );
spdlog::info( "\033[43m\033[30m {1:<{0}} \033[m", 120, "message" );

If I understand your question correctly, you want to format your spdlog output using fmt, rather than having to specify the escape sequences yourself. For this, you can use the fmt::format function and use its output as a variable for spdlog:
#include <spdlog/spdlog.h>
#include <spdlog/fmt/bundled/color.h>
int main(){
spdlog::info( "Printing a string formatted with fmt: {}",
fmt::format(
fmt::bg( fmt::terminal_color::yellow ) |
fmt::fg( fmt::terminal_color::black ) |
fmt::emphasis::bold,
"message"
)
);
return 0;
}

Related

How to resolve "Make sure the web address //ieframe.dll/dnserrordiagoff.htm# is correct" error in wxWebView (wxWidgets)

I am using wxWebView for showing our page content and when I don't have any content for the page, i.e. page is blank, I see the following error:
I have my own file system handler class derived from wxWebViewHandler like below and in GetFile function, I set the content of page. Everything works fine except when page does not have any content. Maybe I should return something else.
struct WxHtmlFSHandler: public wxWebViewHandler
{
WxHtml* dst_;
WxHtmlFSHandler( const wxString& scheme, WxHtml* dst ): wxWebViewHandler( scheme ), dst_( dst )
{ }
wxFSFile* GetFile( const wxString& uri ) override;
~WxHtmlFSHandler()
{
dst_ = nullptr;
}
};
...
if( dst_ && !uri.empty() )
{
if( uri.Contains( dst_->defaultURL_ ) )
{
// load the page's content
//if( !dst_->currentPage_.empty() )
return new wxFSFile( new wxMemoryInputStream( dst_->currentPage_.data(), dst_->currentPage_.size() ),
uri, wxT( "text/html" ), dst_->currentAnchor_
#if wxUSE_DATETIME
, wxDateTime::Now()
#endif
);
...
}
I am also using IE engine for now.
#if wxUSE_WEBVIEW_IE
wxWebViewIE::MSWSetEmulationLevel( wxWEBVIEWIE_EMU_IE11 );
#endif
I am using wxWidgets 3.1.5 on Win 10.
So the problem is when the page content is empty. So I just tried to add a space char to my memory input stream like below and see the effect. It seems working!
Basically I replaced
return new wxFSFile( new wxMemoryInputStream( "", 0 ),
uri, wxT( "text/html" ), dst_->currentAnchor_
#if wxUSE_DATETIME
, wxDateTime::Now()
#endif
);
with
return new wxFSFile( new wxMemoryInputStream( " ", 1 ),
uri, wxT( "text/html" ), dst_->currentAnchor_
#if wxUSE_DATETIME
, wxDateTime::Now()
#endif
);
and now page is blank and does not show anything as expected. I don't know whether this hack is good or even correct, so if anyone has a better answer, please let me know.

How to print filename and function name using spdlog?

https://spdlog.docsforge.com/v1.x/3.custom-formatting/#customizing-format-using-set_pattern
Following spdlog documentation I was able to modify the print pattern
#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"
int main()
{
spdlog::set_pattern("%H:%M:%S.%e %t %s %! %v");
auto logger = spdlog::daily_logger_mt("daily_logger", "../../../logs/daily.txt", 2, 30);
logger->info("casdc");
return 0;
}
With the above I see daily_logger.txt contents below:
01:41:35.895 70101 casdc
01:44:22.719 71978 casdc
01:44:35.225 72232 casdc
But I was expecting to see also:
%s Basename of the source file
%! Source function
Why I'm not seeing those?
Actually it seems to work if I call
SPDLOG_LOGGER_INFO(logger, "{:>10}", "vsvfsdfv");
But then my question is when should I call
logger->info("casdc");

Read json with rapidjson pointer

Trying to integrate rapidjson into my app. Used to read a (validated with an online tool) simple config file like:
{
"filecontent": "appsettings",
"fileversion": 1,
"appsettings": {
"general": {
"sync": "false",
"sound": "true"
},
...
This is my code:
QString path = keypath( key ); //.prepend("/");
rapidjson::Value* hello = rapidjson::Pointer( "/appsettings/general/sound" ) //path.toStdString().c_str()
.Get(rapidJsonDoc_);
if ( hello ) {
QVariant retStr( hello->GetString() );
qDebug()<<"--> " <<path<<" --> " << retStr;
ret = QVariant::fromValue( retStr );
}else{
qDebug()<<"Value not found!";
}
return ret;
If I prepend the pointer string with /, as I understand the examples, it says value not found.
If I remove the slash, if (hello) is true, but does not return an expected value.
rapidJsonDoc_ is of type rapidjson::Document.
Please help me with the correct syntax. I am looking at the source code of rapidjson and can't understand a thing, it is so full of templates and complex signatures...
update:
according to this post modifying a Qt QJsonDocument is not possible like I want.

boost log format single attribute with logging::init_from_stream

When I set up format params in code, to format date time output I can use something like this
logging::formatter simpleFormat(expr::format("%1% %2%") %
expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%H:%M:%S") %
expr::smessage
);
But when I initialize logger with a config file, I can specify format only in attributes position notation, not their format details.
so, this line in a boost log config file
Format="[%TimeStamp%]: %Message%"
produces output:
[2015-Feb-06 09:32:27.401496]: blah blah blah
I want to reduce timestamp to something like this
[06.02.2015 09:32:27]
How can it be described in boost log config file, ot it cant be done at all?
Preamble
My answer is valid for boost 1.55 (haven't tested with latest one). And it was only tested with MSVC 2013 compiler.
Answer
Looks like you need custom formatter_factory for TimeStamp attribute to be able to specify it's format. This works for me:
#include <fstream>
#include "boost/shared_ptr.hpp"
#include "boost/log/trivial.hpp"
#include "boost/log/expressions.hpp"
#include "boost/log/utility/setup.hpp"
#include "boost/log/support/date_time.hpp"
class timestamp_formatter_factory :
public boost::log::basic_formatter_factory<char, boost::posix_time::ptime>
{
public:
formatter_type create_formatter(boost::log::attribute_name const& name, args_map const& args)
{
args_map::const_iterator it = args.find("format");
if (it != args.end())
return boost::log::expressions::stream << boost::log::expressions::format_date_time<boost::posix_time::ptime>(boost::log::expressions::attr<boost::posix_time::ptime>(name), it->second);
else
return boost::log::expressions::stream << boost::log::expressions::attr<boost::posix_time::ptime>(name);
}
};
int main()
{
// Initializing logging
boost::log::register_formatter_factory("TimeStamp", boost::make_shared<timestamp_formatter_factory>());
boost::log::add_common_attributes();
std::ifstream file("settings.ini");
boost::log::init_from_stream(file);
// Testing
BOOST_LOG_TRIVIAL(info) << "Test";
return 0;
}
And now it your settings file you can specify format argument for TimeStamp attribute. Like this:
[Sinks.ConsoleOut]
Destination=Console
AutoFlush=true
Format="[%TimeStamp(format=\"%Y.%m.%d %H:%M:%S\")%]: %Message%"
You should be able to use set_formatter as documented here
sink->set_formatter
(
expr::stream << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
);

Parse and remove part of a QString

I want to parse some kind (or pure) XML code from a QString.
My QString is like:
<a>cat</a>My cat is very nice.
I want to obtain 2 strings:
cat, and My Cat is very nice.
I think a XML parser is not maybe necessary, but in the future I will have more tags in the same string so it's also a very interesting point.
In Qt you have the QRegExp class that can help you to parse your QString.
According to Documentation example:
QRegExp rxlen("^<a>(.*)</a>(.*)$");
int pos = rxlen.indexIn("<a>cat</a>My cat is very nice.");
QStringList list
if (pos > -1) {
list << = rxlen.cap(1); // "cat"
list << = rxlen.cap(2); // "My cat is very nice."
}
The QStringList list will contain the cat and My cat is very nice.
You could use a regular expression <a>(.*)</a>(.*).
If you use Boost you could implement it like follows:
boost::regex exrp( "^<a>(.*)</a>(.*)$" );
boost::match_results<string::const_iterator> what;
if( regex_search( input_string, what, exrp ) ) {
std::string tag( what[1].first, what[1].second );
std::string value( what[2].first, what[2].second );
}